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

时间:2019-02-02 17:00:29

标签: r shiny

我正在构建我的第一个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忙于Web应用。

如果我输入一个无功值,例如values <- reactiveValues() and then value$df <- user_features3,则可以修改此无功值,但在应用运行时,我无法以类似方式访问非无功值。

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

1 个答案:

答案 0 :(得分:0)

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

在除了所有其他shiny的教程,建议你了解variable scope在光泽,特别陈述如

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

话虽如此,2级提供的解决方案。

活性帧(鼓励!)

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)

两者都允许测序如下面的屏幕截图展示。许多人会争辩说,第一个(反应性)示例更清洁,更安全。 (对我来说,<<-的威慑力就足够了!)

steps of adding data to the non-reactive frame