【问题标题】:Dataset (a reactiveValue) can not be found inside regular R functions在常规 R 函数中找不到数据集(反应值)
【发布时间】:2017-05-30 20:40:57
【问题描述】:

我有一个数据集(称为 mydata$data),我想随时保持更新。首先,该数据集作为“原始数据”读入。然后它由几个常规 R 函数更新。

以下是我的代码。当我运行该应用程序时,我总是收到此错误。

Warning: Error in <-: object 'mydata' not found
Stack trace (innermost first):
    106: PrepareData [./functions-sample.R#2]

有人可以帮忙吗?我应该如何定义该数据集?如何使用常规 R 函数对其进行更新?

原始数据:

colA <- c('A','B','C','D','E')
colB <- c(1,2,3,4,5)
rawdata <- as.data.frame(cbind(colA,colB))
View(rawdata)

ui.R:

fluidPage(
  sidebarPanel(
    actionButton("runButton", strong("Run!"))
  ),
  mainPanel(
    tabsetPanel(id = "allResults",
              tabPanel(value='inputVars',title='Variable', DT::dataTableOutput('inputVars')),
              tabPanel(value='result',title='Result', DT::dataTableOutput('result')),
              tabPanel(value='temp',title="TEMP", verbatimTextOutput("temp"))
    )
  )
)

服务器.R:

source("./functions-sample.R")

function(input, output, session) {

  # Activate tab 'Result' when users click 'Run'
  observeEvent(input$runButton, {
    updateTabsetPanel(session, "allResults", 'result')
  })

  mydata <- reactiveValues()

  ### RESULT TAB ###

  # mydata$data is the active dataset we want to keep updating
  result <- eventReactive (input$runButton, {
    mydata$data <- rawdata
    PrepareData(mydata$data)
    head(mydata$data,5)
  })

  ### RENDERING FUNCTIONS ###

  # Default SummaryTable
  output$inputVars <- DT::renderDataTable({
      DT::datatable(rawdata, options = list(paging = FALSE, searching = FALSE))
  })

  # Display results
  output$result <- DT::renderDataTable({
    DT::datatable(result(), options = list(paging = FALSE, searching = FALSE))
  })

  output$temp <- renderPrint({
    print(head(mydata$data))
  })
}

functions-sample.R:

PrepareData<-function(datax) {
  mydata$data <- RankData(datax)
  CodeMissingData(mydata$data)
}

RankData<-function(datax) {
  return(datax[order(datax[,1],datax[,2]),])
}

CodeMissingData<-function(datax) {
  for (v in 4:ncol(datax)) {
    if (!("*NA*" %in% levels(datax[,v]))) {levels(datax[,v])<<-c(levels(datax[,v]),"*NA*")}
  }
  datax[,-(1:3)][is.na(datax[,-(1:3)]) | datax[,-(1:3)]=="NA"]<<-"*NA*"
  mydata$data <- datax
}

【问题讨论】:

    标签: r shiny


    【解决方案1】:

    尝试从您的函数返回数据而不是修改它:

    CodeMissingData<-function(datax) {
      for (v in 4:ncol(datax)) {
        if (!("*NA*" %in% levels(datax[,v]))) {levels(datax[,v])<-c(levels(datax[,v]),"*NA*")}
      }
      datax[,-(1:3)][is.na(datax[,-(1:3)]) | datax[,-(1:3)]=="NA"]<-"*NA*"
      return(datax)
    }
    
    PrepareData<-function(datax) {
      CodeMissingData(RankData(datax))
    }
    

    然后在server.R中

     result <- eventReactive (input$runButton, {
        mydata$data <- PrepareData(rawdata)
        head(mydata$data,5)
      })
    

    【讨论】:

    • 那行得通。谢谢!让函数返回反应性数据集(而不是修改它)是一般规则/最佳实践吗?再次感谢!
    • 一个函数应该总是返回一个值/永远不要修改超出其范围的对象。
    • 知道了。再次感谢!
    • 还有一个问题。我是否正确得出结论,我们不能从 Shiny 应用程序中的函数修改全局变量/数据集?例如,在下面的函数中,我正在修改一个名为 data 的全局变量(数据框)。 PrepareData&lt;-function(pickoneperday=TRUE) { set.seed(1) if (pickoneperday==TRUE) {data&lt;&lt;-PickOnePerDay(data)} data&lt;&lt;-RankData(data) SetMeasureType() minnodebase&lt;&lt;-0.005*nrow(data) CodeMissingData(data) }
    • 你可以修改全局变量,这就是&lt;&lt;-的作用,有时你必须这样做,但通常你可以避免它,你真的应该这样做。
    猜你喜欢
    • 2017-10-29
    • 2015-03-13
    • 2018-08-25
    • 1970-01-01
    • 1970-01-01
    • 2020-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多