修改并组合用户在闪亮的应用程序中上传的反应数据框

时间:2016-12-15 12:46:07

标签: r user-input shiny shiny-reactivity

我正在创建一个闪亮的应用程序,其中一部分是根据用户上传和修改的数据计算线性回归模型。 我正在一步一步地做所有事情,所以在这里我将只向您展示一个关于主要问题的测试应用程序的代码。这个想法是:

  1. 用户使用闪亮的<{1}}
  2. 从.csv文件上传数据
  3. 数据显示,然后在检查后,用户可以修改 他选择的变量
  4. 每个选定和修改的变量都会显示旧变量 作为一个新的反应数据表 - 我设法通过它的帮助来完成它 这个: Add values to a reactive table in shiny
  5. 现在,当指定初始数据集时,这一切都可以正常使用下面的代码:

    fileInput

    但是,当我想要包含第一步,即上传运行应用程序的 AFTER 数据集时,应用程序无法启动,因为现在我指的是可能没有的反应性内容存在。这是一个更新的代码,具有从您自己的来源上传数据的功能:

    test_df <- data.frame(a = seq(1000, 21000, 1000), b = seq(1:21), c = seq(100, 300, 10))
    
    library(shiny)
    
    runApp(list(
      ui=pageWithSidebar(headerPanel("Adding entries to table"),
                     sidebarPanel(uiOutput("select1"),
                                  selectInput("select2", "Choose modification",
                                              choices = c("log", "different"), 
                                              selected = NULL, multiple = F),
                                  actionButton("update", "Update Table")),
                     mainPanel(tableOutput("table1"))),
    
    server=function(input, output, session) {
    
    values <- reactiveValues()
    
    ### specifing the dataset ###
    values$df <- data.frame(test_df)
    nr <<- nrow(test_df)
    
    ### this will contain the modified values ###
    values$d <- data.frame(1:nr)
    
    ### selecting a variable to modify ###
    output$select1 <- renderUI({
      nc <- ncol(values$df)
      nam <- colnames(values$df)
      selectInput("var", label = "Select var:",
                  choices = c(nam), multiple = F,
                  selected = nam[1])
    })
    
    ### calculations needed for modifactions ###
    newEntry <- observeEvent(input$update, {
    
      if(input$select2 == "log") {
        newCol <- isolate(
          c(log(values$df[input$var]))
        )
        newCol <- as.data.frame(newCol)
        colnames(newCol) <- paste0("Log of ", input$var)
      } 
    
      else if(input$select2 == "different") {
        newCol <- isolate(
          c(1-exp(-(values$df[input$var]/100)))
        )
        newCol <- as.data.frame(newCol)
        colnames(newCol) <- paste0(input$var, "Diff of", input$dr1)
      } 
      ### adding new modified columns to the dataframe ###
      isolate(
        values$d <- dplyr::bind_cols(values$d, newCol)
      )
    
    })
    
    output$table1 <- renderTable({
      d1 <- values$d
      nc <- ncol(d1)
    
      ### printing the whole dataframe (initial+modified) - skipping ###
      ### the first column of modified values, as it doesn't contain our data ###
      if(input$update == 0) {
        print(data.frame(test_df))
      } else {
        data.frame(values$df, d1[2:nc])
      }
    })
    
    }))
    

    我得到的错误:

      

    .getReactiveEnvironment()中的错误$ currentContext:不允许操作&gt;没有活动的响应上下文。 (你试图做一些只能在反应式表达式或观察者中完成的事情。)

    当然,我遗漏了一些关于Shiny的反应性的东西,但是我彻底阅读了很多不同的文章,问题等,但找不到这个问题的答案。这不是上传文件本身的问题,因为当我将反应数据集写入正常变量时,这段代码在不同的应用程序中完美运行,然后再引用它的内容。但是,在将数据写入library(shiny) runApp(list( ui=pageWithSidebar(headerPanel("Adding entries to table"), sidebarPanel(fileInput("file1", "Choose file to upload", accept = c("text/csv", "text/comma-separated-values", "text/tab-separated-values", "text/plain", ".csv",".tsv")), checkboxInput("header", "Header", TRUE), radioButtons("sep", "Separator",c(Comma=",",Semicolon=";",Tab="\t"),","), radioButtons("dec", "Decimal",c(Comma=",",Dot="."),","), actionButton("Load", "Load the File"), uiOutput("select1"), selectInput("select2", "Choose modification", choices = c("log", "different"), selected = NULL, multiple = F), actionButton("update", "Update Table")), mainPanel(tableOutput("table1"))), server=function(input, output, session) { values <- reactiveValues() ### uploading data from external source ### data1 <- reactive({ if(input$Load == 0){return()} inFile <- input$file1 if (is.null(inFile)){return(NULL)} isolate({ input$Load my_data <- read.csv(inFile$datapath, header = input$header, sep = input$sep, stringsAsFactors = FALSE, dec = input$dec) }) my_data }) ### specifing the dataset ### values$df <- data.frame(data1()) nr <<- nrow(data1()) ### this will contain the modified values ### values$d <- data.frame(1:nr) ### selecting a variable to modify ### output$select1 <- renderUI({ nc <- ncol(values$df) nam <- colnames(values$df) selectInput("var", label = "Select var:", choices = c(nam), multiple = F, selected = nam[1]) }) ### calculations needed for modifactions ### newEntry <- observeEvent(input$update, { if(input$select2 == "log") { newCol <- isolate( c(log(values$df[input$var])) ) newCol <- as.data.frame(newCol) colnames(newCol) <- paste0("Log of ", input$var) } else if(input$select2 == "different") { newCol <- isolate( c(1-exp(-(values$df[input$var]/100))) ) newCol <- as.data.frame(newCol) colnames(newCol) <- paste0(input$var, "Diff of", input$dr1) } ### adding new modified columns to the dataframe ### isolate( values$d <- dplyr::bind_cols(values$d, newCol) ) }) output$table1 <- renderTable({ d1 <- values$d nc <- ncol(d1) ### printing the whole dataframe (initial+modified) - skipping the first ### ### column of modified values, as it doesn't contain our data ### if(input$update == 0) { print(data.frame(test_df)) } else { data.frame(values$df, d1[2:nc]) } }) })) 时,如何在此处执行此操作?或者也许有另一种解决方案来处理来自外部源的反应数据,这种方式?希望我把事情弄清楚。

1 个答案:

答案 0 :(得分:1)

感谢@StéphaneLaurent的帮助!全局变量nr仍然存在一些问题,但以下更改使其有效。

首先我指定测试数据,它将在用户加载任何数据之前显示(因此应用程序有一些计算基础,而不是空值): test_df <- data.frame(a = seq(1000, 21000, 1000), b = seq(1:21), c = seq(100, 300, 10))

然后我在指定反应数据帧时使用它,以防没有任何用户输入:

  data1 <- reactive({
  if(input$Load == 0){return(test_df)}
  inFile <- input$file1
  if (is.null(inFile)){return(test_df)}

  isolate({ 
    input$Load
    my_data <- read.csv(inFile$datapath, header = input$header, sep = input$sep, stringsAsFactors = FALSE, dec = input$dec)
  })
  my_data
})

最后,我将observe函数用于依赖于其他一些反应变量的变量:

observe({
  values$df <- data.frame(data1())
  nr <- nrow(data1())
  values$d <- data.frame(1:nr)
})

其余代码不需要任何进一步的更改,现在应用程序完全正常。