2

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

  1. fileInput用户使用in shiny从 .csv 文件上传数据
  2. 数据显示,然后,在检查后,用户可以修改他选择的变量
  3. 每个选定和修改的变量都与旧变量一起显示为一个新的反应数据表 - 我在这个的帮助下设法通过它: 将值添加到闪亮的反应表

现在,当指定初始数据集时,下面的代码一切正常:

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])
  }
})

}))

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

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])
  }
})

}))

我得到的错误:

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

当然,我错过了关于 Shiny 反应性的一些东西,但我彻底阅读了很多不同的文章、问题等,但找不到这个问题的答案。上传文件本身不是问题,因为在引用其内容之前,当我将反应数据集写入普通变量时,这段代码可以在不同的应用程序中完美运行。但是,当将数据写入时,我怎么能在这里做到这一点values$...?或者也许有另一种解决方案可以以这种方式处理来自外部源的反应数据?希望我把一切都说清楚了。

4

1 回答 1

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)
})

其余代码不需要任何进一步的更改,应用程序现在运行良好。

于 2016-12-27T10:17:12.933 回答