【问题标题】:Modifying a Non-Reactive R Dataframe while running Shiny App在运行 Shiny App 时修改非反应式 R 数据框
【发布时间】:2019-02-02 17:00:29
【问题描述】:

我正在构建我的第一个 Shiny 应用程序,但遇到了一些麻烦。

当我为应用注册新用户时,我需要在数据框中添加一行包含一些空值的行,用于生成推荐。

user_features3 <- rbind(user_features3,c(612,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0))

当应用程序未运行时,这可以正常工作,并且添加了第 612 行。但是在它运行时,这对 user_features3 没有影响。我认为这可能是因为 R 正忙于 webapp。

如果我创建了一个响应式值,比如values <- reactiveValues() and then value$df <- user_features3,我可以修改这个响应式值中的值,但我无法在应用程序运行时以类似的方式访问非响应式值。

我需要实时更新它,以便我可以使用它来生成电影推荐。有什么建议吗?

【问题讨论】:

    标签: r shiny


    【解决方案1】:

    这解决了您提出的问题,但修改非反应性变量也会导致问题。一般来说,考虑在shiny 环境中修改非反应性变量表明您可能没有考虑如何扩展或存储或正确维护应用程序状态。例如,如果您希望有多个用户,那么要知道此数据不与其他用户共享,它只是当前用户。使用局部变量无法解决这个问题。 (如果您需要在用户之间“共享”某些内容,您确实需要一个数据后端,例如某种形式的 SQL,包括 SQLite。请参阅:https://shiny.rstudio.com/articles/persistent-data-storage.html

    除了所有其他 shiny 教程之外,我建议您阅读有关 variable scope 的闪亮说明,特别是诸如

    • “一个只读数据集,将在 Shiny 启动时加载一次,并且可供每个用户会话使用”,谈论存储在 server 函数定义之外的数据;
    • “[这个变量]的这个本地副本在其他会话中不可见”,谈论存储在server函数中的变量;和
    • “在global.R 中定义的对象与在服务器函数定义之外的app.R 中定义的对象类似”

    话虽如此,有两个提供了解决方案。

    反应式框架(鼓励!)

    library(shiny)
    
    ui <- fluidPage(
      # App title ----
      titlePanel("Hello Shiny!"),
      sidebarLayout(
        sidebarPanel(
          textInput(inputId = "sometext", label = "Some Text:",
                    placeholder = "(nothing meaningful)"),
          actionButton(inputId = "addnow", label = "Add!")
        ),
        mainPanel(
          tableOutput("myframe")
        )
      )
    )
    
    server <- function(input, output, session) {
      rxframe <- reactiveVal(
        data.frame(txt = character(0), i = integer(0),
                   stringsAsFactors = FALSE)
      )
      observeEvent(input$addnow, {
        newdat <- data.frame(txt = isolate(input$sometext),
                             i = nrow(rxframe()) + 1L,
                             stringsAsFactors = FALSE)
        rxframe( rbind(rxframe(), newdat, stringsAsFactors = FALSE) )
      })
      output$myframe <- shiny::renderTable( rxframe() )
    }
    
    shinyApp(ui, server)
    

    此示例使用shiny::reactiveVal,尽管使用shiny::reactiveValues 也同样容易(如果正在使用多个反应变量)。


    非反应性框架(不鼓励)

    library(shiny)
    
    ui <- fluidPage(
      # App title ----
      titlePanel("Hello Shiny!"),
      sidebarLayout(
        sidebarPanel(
          textInput(inputId = "sometext", label = "Some Text:",
                    placeholder = "(nothing meaningful)"),
          actionButton(inputId = "addnow", label = "Add!")
        ),
        mainPanel(
          tableOutput("myframe")
        )
      )
    )
    
    server <- function(input, output, session) {
      nonrxframe <- data.frame(txt = character(0), i = integer(0),
                               stringsAsFactors = FALSE)
      output$myframe <- shiny::renderTable({
        req(input$addnow)
        nonrxframe <<- rbind(nonrxframe,
                             data.frame(txt = isolate(input$sometext),
                                        i = nrow(nonrxframe) + 1L,
                                        stringsAsFactors = FALSE),
                             stringsAsFactors = FALSE)
        nonrxframe
      })
    }
    
    shinyApp(ui, server)
    

    两者都允许排序,如下面的屏幕截图所示。许多人会争辩说,第一个(反应式)示例更清洁、更安全。 (只是使用&lt;&lt;- 对我来说就足够了!)

    【讨论】:

    • Angad Singh,这能回答你的问题吗?如果有,请accept it;这样做不仅为回答者提供了一些积分,而且还为有类似问题的读者提供了一些关闭。 (如果仍有问题,您可能需要编辑您的问题并提供更多详细信息。)
    猜你喜欢
    • 2017-01-17
    • 2013-12-22
    • 1970-01-01
    • 2015-08-07
    • 2020-03-24
    • 1970-01-01
    • 2020-02-12
    • 2020-12-20
    • 2019-05-31
    相关资源
    最近更新 更多