操纵Shiny中的反应对象 - 在< - 中的错误:赋值的左侧无效(NULL)

时间:2017-06-07 11:33:58

标签: r shiny reactive

我一次又一次地遇到错误“< - :invalid(NULL)左侧的错误”一遍又一遍,因为我试图在Shiny中采取一个被动对象并进一步操纵它。我在下面提供了一个说明性示例。

 testdf <- data.frame(row1 = c(1,3,6), row2 = c(7, 5, 1))

 ui <- fluidPage(

   titlePanel("Education in Tanzania"),

   sidebarLayout(
     sidebarPanel(


       #Select aggregation level of data
       selectInput("AggregationSelect", 
                   label = "Aggregation",
                   choices = list("School" = 1, 
                                  "District" = 2, 
                                  "Region" = 3),
                   selected = 1)
     ),

     mainPanel(
       DT::dataTableOutput("OutputTable")
     )
   )
 )

 server <- function(input, output) {

     Output1 <- reactive({
         testdf
     })

   observe({
     if(2 %in% input$AggregationSelect) {
       observe({Output1()$name[3] <- "b"})
     } else  if(3 %in% input$AggregationSelect) {
       observe({Output1()$name[2] <- "c"})
     } else  if(1 %in% input$AggregationSelect) {
       observe({Output1()$name[1] <- "a"})
     }
   })

   output$OutputTable <- {DT::renderDataTable({
     DT::datatable(Output1(),
                   options = list(pagelength = 25,
                                  searching = TRUE,
                                  paging = TRUE,
                                  lengthChange = FALSE),
                   rownames = FALSE)
     })
   }
 }  

 shinyApp(ui = ui, server = server)

我在实际代码中需要做的是通过UI组装数据帧(我能够做到这一点,因此在这里只是附加了一个随机df)然后添加一些信息(这里用添加的“名称表示”) “列”基于在UI中选择的内容。似乎将列添加到df应该不是那么困难,但在反应对象上下文中,我尝试过的任何东西都没有用。修改被动对象的其他方法是受欢迎的,只要它们可以应用于更复杂的多步骤场景 - 我无法将我需要的所有内容捆绑到反应对象的初始分配中。

3 个答案:

答案 0 :(得分:1)

  1. 无法从外部修改反复表达式。您只能修改被动值。

  2. 通常,您永远不需要使用observe。如果您不需要副作用,请使用反应性表达,在需要时使用observeEvent的反应值。

  3. 必须在继续之前阅读被动教程。在你做任何复杂的事情之前,有一些概念需要被理解,特别是强制更新习惯&#34;。你需要让Shiny正确地进行更新并正确设置逻辑。

  4. 我建议您阅读RStudio网站上有关被动反应的所有教程,文章,然后观看the reactive tutorial video in Shiny conference

答案 1 :(得分:0)

我不是100%你在做什么,但我认为如果你使用eventReactive来听你的selectInput,那就最好了。请注意,我将变量names添加到数据框:

library(shiny)
testdf <- data.frame(names = c(1,3,6), row2 = c(7, 5, 1))

ui <- fluidPage(
  titlePanel("Education in Tanzania"),
  sidebarLayout(
    sidebarPanel(
      #Select aggregation level of data
      selectInput("AggregationSelect", label = "Aggregation",
                  choices = list("School" = 1, "District" = 2, "Region" = 3),selected = 1)
    ),
    mainPanel(
      DT::dataTableOutput("OutputTable")
    )
  )
)

server <- function(input, output) {

  Output1 <- eventReactive(input$AggregationSelect,{
    if(input$AggregationSelect %in% "2"){
      testdf$name[3] <- "b"
      return(testdf)
    }
    else if(input$AggregationSelect %in% "3"){
      testdf$name[2] <- "c"
      return(testdf)
    }
    else if(input$AggregationSelect %in% "1"){
      testdf$name[1] <- "a"
      return(testdf)
    }
    else{
      return(testdf)
    }
  })

  output$OutputTable <- {DT::renderDataTable({
    print(Output1())
    DT::datatable(Output1(),options = list(pagelength = 25,searching = TRUE,paging = TRUE,lengthChange = FALSE),rownames = FALSE)
  })
  }
}  

shinyApp(ui = ui, server = server)

enter image description here

答案 2 :(得分:0)

根据我对您的问题的理解,我已经调整了您的代码如下:

testdf <- data.frame(name = c(1,2,3), freq = c(100, 200, 300))

ui <- fluidPage(

titlePanel("Education in Tanzania"),

sidebarLayout(
sidebarPanel(


  #Select aggregation level of data
  selectInput("AggregationSelect", 
              label = "Aggregation",
              choices = list("School" = 1, 
                             "District" = 2, 
                             "Region" = 3))
),

mainPanel(
  DT::dataTableOutput("OutputTable")
 )
))

server <- function(input, output) {

Output1 <- reactive({
input$AggregationSelect
selection <- input$AggregationSelect

if(2 %in% selection){
  testdf$name[3] <- "b"
} 
else if(3 %in% selection){
  testdf$name[2] <- "c"
} 
else if(1 %in% selection){
  testdf$name[1] <- "a"
}
testdf
})

output$OutputTable <- {DT::renderDataTable({
DT::datatable(Output1(),
              options = list(pagelength = 25,
                             searching = TRUE,
                             paging = TRUE,
                             lengthChange = FALSE),
              rownames = FALSE)
})
}}  

shinyApp(ui = ui, server = server)

app