【发布时间】:2021-05-06 16:03:19
【问题描述】:
我想安全地允许我的应用用户能够在我的闪亮应用中操作数据集 - 通过将代码传递给数据 %>% mutate (input$textInput1),然后更新包含被操作数据的反应值, v$data.
对于如何使用单个预先命名的输入并对其进行解析有一些答案,但我无法推断如何为多个文本输入定义它。 例如'input$textinput1','input$textinput2'..
在激活输入字段的情况下按下重新编码按钮会导致错误:
Warning: Error in : Problem with `mutate()` input `..1`. x <text>:1:1: unexpected '[[' 1: [[ ^ ℹ Input `..1` is `eval.secure(parse(text = paste0("[[input$recode_call", >i, "]]")))`. 94: <Anonymous>
library(ggplot2)
library(shiny)
library(DT)
library(dplyr)
library(plotly)
library(colourpicker)
library(RAppArmor)
server <- shinyServer(function(input, output, session){
#Tracks user changes to input
v <- reactiveValues(data=NULL, print_execute_complete=NULL)
#For development, mtcars
myData <- reactive({
return(mtcars)
})
#Count the number of recoding terms to render
counter <- reactiveValues(n = 0)
observeEvent(input$add_recode, {counter$n <- counter$n + 1})
observeEvent(input$rm_recode, {
if(counter$n > 0) counter$n <- counter$n - 1
})
#Recoding button functionality
recoding_i <- reactive({
n <- counter$n
if(n>0){
isolate({
lapply(seq_len(n),function(i){
fluidRow(
column(width=4,
textInput(inputId = paste0('recode_call',i),
label=paste0('Recode_',i)))
)
}
)
})
}
})
#Render the dynamic UI
output$recoding <- renderUI({ recoding_i() })
#Observes press of recode button.
observeEvent(input$'execute_recode',{
v[["print_execute_complete"]] <- TRUE
})
#Observes press of reset button.
observeEvent(input$'reset_recode',{
v[["print_execute_complete"]] <- FALSE
})
#Loop over recoding input boxes.
observeEvent(v$print_execute_complete, {
if(v[["print_execute_complete"]] == TRUE){
if(counter$n==0|is.null(counter$n)){
return(myData())
} else {
lapply(seq_len(counter$n), function(i){
if(is.null((v[["data"]]))){
v$data <- myData() %>% mutate(eval.secure(parse(text=paste0('[[input$recode_call',i,']]'))))
} else {
v$data <- v[["data"]] %>% mutate(eval.secure(parse(text=paste0('[[input$recode_call',i,']]'))))
}
}
)
}
}
})
#Confirmation text
output$execute_complete <- renderText({
req(v[["print_execute_complete"]])
if(v[["print_execute_complete"]] == TRUE){
"Recoding Complete."
}
})
#Render recoded data table
output$recoded_dt <- DT::renderDataTable({
req(v[["print_execute_complete"]] == TRUE)
if(!is.null(v[["data"]])){
return(DT::datatable(v[["data"]], filter='top'))
} else {
return(iris)#DT::datatable(myData(),filter='top'))
}
})
}
)
ui <- shinyUI(fluidPage(
titlePanel("Something is Wrong"),
# Input: Select a file ----
navlistPanel(
tabPanel("Recoding",
h3("Instruction"),
fluidRow(p("Write a functional call in one of the action boxes below. A call takes the form of one of the following :"
,style="font-family: 'times'; font-si16pt")
),
fluidRow(actionButton('add_recode', 'Add recode term'),
actionButton('rm_recode', 'Remove recode term')),
br(),
br(),
uiOutput('recoding'),
br(),
br(),
fluidRow(actionButton('execute_recode', "Recode",icon = icon('angle-double-right')),
actionButton('reset_recode', "Reset", icon=icon('angle-double-right'))),
textOutput('execute_complete'),
br(),
br(),
br(),
DT::dataTableOutput('recoded_dt')
)
)
)
)
shinyApp(ui, server)
【问题讨论】:
-
我建议你首先尝试在
shiny之外解决这个问题:定义一个结构input <- list(recode_call = "something your users can do")并弄清楚如何让它在mutate中工作。我怀疑你需要一些元编程,看看rlang和tidyevalvignettes。 -
这可能是shinyAce 的一个很好的用例。
-
@r2evans 花了一两天的时间,但我已经上传了我设法拼凑的代码。谁能改进我对 tidyeval / rlang 如何处理我的电话的回答/解释?