繁体   English   中英

运行Shiny App时修改非反应性R数据框

[英]Modifying a Non-Reactive R Dataframe while running Shiny App

我正在构建我的第一个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 ,则可以修改此无功值,但是当应用正在运行。

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

这可以解决您的问题,但是修改非反应变量也会引起问题。 通常,考虑在shiny环境中修改非反应变量意味着您可能没有考虑如何扩展或存储或正确维护应用程序状态。 例如,如果您期望有多个用户,则知道该数据未与其他用户共享,则仅是当前用户。 使用局部变量无法解决此问题。 (如果需要在用户之间“共享”某些东西,则确实需要数据后端,例如某种形式的SQL,包括SQLite。请参阅: https : //shiny.rstudio.com/articles/persistent-data-storage.html

除了所有其他shiny教程之外,我建议您阅读闪亮的变量范围 ,特别是诸如

  • “一个只读数据集,它将在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)

两者都允许排序,如下面的屏幕快照所示。 许多人会争辩说,第一个(反应性)示例更清洁,更安全。 (仅使用<<-就足以威慑我了!)

将数据添加到非反应性框架的步骤

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM