我正在构建一个闪亮的应用程序。我尝试将用户选择为 char 的函数保存到
data.frame()
中,然后使用 paste()
生成类似“n = n(), sum = sum(value), Mean = Mean(value)”或更短的内容,最后传递给 summarise()quote()
和eval(parse())
,都失败了。
library(shiny)
library(shinyjs)
library(tidyverse)
ui <- fluidPage(
useShinyjs(),
fluidRow(
column(width = 3,
wellPanel(
selectInput("data_groupby", label = "group_by", choices = c(Choose = "", "group", "sameple", "var"), selected = c("group", "var"), multiple = TRUE),
actionButton("data_groupby_ok", "click here to group_by"),
selectInput("data_summarise_fun", "Function", choices = c(Choose = "", "n", "sum", "mean")),
actionButton("data_summarise_add", "Summarise"),
h4("paras to be passed to summarise():"),
verbatimTextOutput("summarise_paras")
)
),
column(width = 3,
h4("data:"),
verbatimTextOutput("data")
),
column(width = 3,
h4("data_summarised:"),
verbatimTextOutput("data_summarised")
),
column(width = 3,
h4("data_desired (if add 3 functions):"),
verbatimTextOutput("data_desired")
)
)
)
server <- function(input, output, session) {
aggr <- reactiveValues(
data = NULL,
summarise_paras = data.frame(column = character()),
data_grouped = NULL,
data_summarised = NULL,
data_desired = NULL
)
set.seed(50)
aggr$data <- data.frame(
group = rep(LETTERS[1:3], each = 6),
sample = rep(c(paste0("A_", 1:3), paste0("B_", 1:3), paste0("C_", 1:3)), each = 2),
var = rep(c("height", "weight"), times = 9),
value = runif(18, min = 0, max = 1)
)
aggr$data_desired <- data.frame(
group = rep(LETTERS[1:3], each = 6),
sample = rep(c(paste0("A_", 1:3), paste0("B_", 1:3), paste0("C_", 1:3)), each = 2),
var = rep(c("height", "weight"), times = 9),
value = runif(18, min = 0, max = 1)
) %>%
group_by(group, var) %>% summarise(n = n(), sum = sum(value), mean = mean(value))
observeEvent(input$data_groupby_ok, {
groupby <- input$data_groupby
aggr$data_grouped <- aggr$data %>% group_by(across(all_of(groupby)))
disable("data_groupby")
})
observe({
toggleState("data_summarise_add", nchar(input$data_summarise_fun) >0)
})
observeEvent(input$data_summarise_add, {
tryCatch({
fun <- input$data_summarise_fun
if (fun == "n") {
para <- "n = n()"
} else if (fun == "sum") {
para <- "sum = sum(value)"
} else if (fun == "mean") {
para <- "mean = mean(value)"
}
aggr$summarise_paras <- aggr$summarise_paras %>%
filter(column != para) %>%
bind_rows(data.frame(column = para))
paras <- paste(aggr$summarise_paras$column, collapse = ",")
aggr$data_summarised <- aggr$data_grouped %>% summarise(enquote(paras))
reset("data_summarise_fun")
}, error = function(e) {
showNotification(paste(e$message), type = "error", duration = 5)
})
})
output$data <- renderPrint({print(aggr$data)})
output$summarise_paras <- renderPrint({print(aggr$summarise_paras)})
output$data_summarised <- renderPrint({print(aggr$data_summarised)})
output$data_desired <- renderPrint({print(aggr$data_desired)})
}
shinyApp(ui = ui, server = server)
我想要的输出是
aggr$data_desired
,它打印在我闪亮的示例中
问题是(大概)你希望这些值是“n = 10,sum = -0.369,mean = -0.036987”之类的东西,但你写的不是这样的 - 这很糟糕,因为它不是有效的 R 代码(在R中你不能只写
x = 1, y = 2
,你会得到错误Error: unexpected ',' in "x = 1,"
,而且因为equals是用于赋值的,而你似乎不想将n()
赋值给变量n
。
一种选择是使用胶水:
data |> summarise(val = glue::glue("n = {n()}, sum = {sum(value)}, mean = {mean(value)}"), .by = c(group, var))
输出:
group var val
1 A a n = 10, sum = -0.369871614091487, mean = -0.0369871614091487
2 A b n = 10, sum = -4.90551745324375, mean = -0.490551745324375
3 A c n = 10, sum = -4.04729937846017, mean = -0.404729937846017
4 A d n = 10, sum = -2.54372850319173, mean = -0.254372850319173
5 B c n = 10, sum = 0.936866512219415, mean = 0.0936866512219415
6 B d n = 10, sum = -3.34912487194284, mean = -0.334912487194284
7 B a n = 10, sum = -0.341116609361569, mean = -0.0341116609361569
8 B b n = 10, sum = -3.18225275070246, mean = -0.318225275070246
9 C a n = 10, sum = -4.74290766135976, mean = -0.474290766135976
10 C b n = 10, sum = 0.112798793892494, mean = 0.0112798793892494
11 C c n = 10, sum = -1.44746005504636, mean = -0.144746005504636
12 C d n = 10, sum = -1.31363366405953, mean = -0.131363366405953
13 D c n = 10, sum = -3.3104100896434, mean = -0.33104100896434
14 D d n = 10, sum = 1.38864716115738, mean = 0.138864716115738
15 D a n = 10, sum = 6.04682327356391, mean = 0.604682327356391
16 D b n = 10, sum = -2.40214704657337, mean = -0.240214704657337
17 E a n = 10, sum = -2.66630215861559, mean = -0.266630215861559
18 E b n = 10, sum = -0.889225624753177, mean = -0.0889225624753177
19 E c n = 10, sum = -6.39670148391452, mean = -0.639670148391452
20 E d n = 10, sum = -4.79912286801664, mean = -0.479912286801664