【问题标题】:on assignment of reactiveValues() empty dataframe created在分配 reactiveValues() 创建的空数据框
【发布时间】:2015-12-15 10:13:55
【问题描述】:

可重现的例子:

server.R

library(shiny)

shinyServer( function(input, output, session) {

    myDf <- reactiveValues(myData = NULL)

    problematicDf <- reactiveValues(test = NULL)

    observeEvent(input$myButton, {
            myDf$myData <- df
    })


    observe({
            output$myTestUi <- renderUI({
                    selectInput(inputId = 'mySelection', 
                                label = 'Selection', 
                                choices = levels(myDf$myData$z),
                                multiple = T,
                                selected = c(levels(myDf$myData$z)[1])
                    )
            })
    })


    observe({
            problematicDf$test <- subset(myDf$myData, ((myDf$myData$z %in% input$mySelection)))
    })


    observe({
            str(problematicDf$test)
    })

    observe({
            as.matrix(x = problematicDf$test)
    })
})

ui.R

library(shiny)

shinyUI( bootstrapPage( 

    h3("Push the button"),
    actionButton(inputId = "myButton",
                 label = "clickMe"),

    h4("Split Merkmal"),
    uiOutput("myTestUi")

))

global.R

df <- data.frame(x = 1:10, y = 10:1, z = letters[1:10])
df$z <- as.factor(df$z)

这给了我:

NULL
[1] "NULL"
NULL
Warning: Unhandled error in observer: 'data' must be of a vector type, was 'NULL'
observe({
    as.matrix(x = problematicDf$test)
})

只看

的输出
observe({
  str(problematicDf$test)
  print(class(problematicDf$test))
  print(problematicDf$test$z)
})

点击action Button后,没有as.matrix,我得到:

NULL
[1] "NULL"
NULL
'data.frame':   0 obs. of  3 variables:
 $ x: int 
 $ y: int 
 $ z: Factor w/ 10 levels "a","b","c","d",..: 
[1] "data.frame"
factor(0)
Levels: a b c d e f g h i j
'data.frame':   1 obs. of  3 variables:
 $ x: int 1
 $ y: int 10
 $ z: Factor w/ 10 levels "a","b","c","d",..: 1
[1] "data.frame"
[1] a
Levels: a b c d e f g h i j

这是有问题的。正如你所看到的,它首先创建了一个df,它有点空,带有占位符,class = NULL。然后,它填补了这一点。但是,似乎其他reactive functions 正在等待创建problematicDf$test尽快 创建空df(使用class = NULL)。他们之后不再更新。它们仅在进行另一个选择时更新。 这会导致(在我的情况下)程序崩溃,因为我需要使用如此创建的 data.frame 继续工作和子集等。

如何处理?! 我可以包含if else 并检查class = NULL。但在我看来,这是一种不雅的方式。

【问题讨论】:

    标签: r shiny reactive-programming


    【解决方案1】:

    你有理由将myDf初始化为NULL吗?如果没有,您可以轻松解决在初始化时分配df 的问题。如果这样做,您的代码也不需要该按钮。

    而且你不应该在observe 中声明你的renderUI。每当您偶然选择了项目时,observe 就会被激活,它会将您的 selectInput 设置为其初始状态(仅选择项目 'a')。

    编辑 1

    #server.R

    shinyServer( function(input, output, session) {
       # initialize myDf$myData with df and problematicDf as NULL
       myDf <- reactiveValues(myData = df)
       problematicDf <- reactiveValues(test = NULL)
    
       # you don't have to observe here. once the selectInput 
       # has been created, you can (un)select how many choices you want
       output$myTestUi <- renderUI({
           selectInput(inputId = 'myTestUi', 
                       label = 'Selection', 
                       choices = levels(myDf$myData$z),
                       multiple = T,
                       # this line determines that ONLY the first item on 
                       # c(levels(myDf$myData$z)[1] is selected on the selectInput initialization!
                       selected = c(levels(myDf$myData$z)[1])
           )
       })
    
       observe({
           problematicDf$test <- subset(myDf$myData, 
                                 (myDf$myData$z %in% input$myTestUi))
       })
    
       observeEvent(input$myButton, {
           # the code in here will only run when the button is pushed!
           print("you should only put things here that you want to be flushed on the button being clicked!")
       })
    
    })
    

    编辑 2

    因此,请将myDf$myData 初始化为NULL,并在observeEvent 中分配df。

    renderUI 将以selectInput 开头,没有任何选择,但只要按下按钮,就会为其分配选择。

    您提到了一些reactive 函数在数据仍为NULL 时崩溃。有很多方法可以解决这个问题。一种方法是只使用您提到的if(is.null(myDf$myData)) return(NULL)。可能不是最优雅的方式,但通常效果很好。其他方式可能包括isolateobserveEvent(默认情况下它不会对 NULL 输入做出反应)。这取决于您的应用程序如何作为一个整体工作。

    但您似乎还没有完全理解反应性和其他闪亮元素的工作原理。尝试阅读 rstudio 文章,特别是“反应式编程”部分 (http://shiny.rstudio.com/articles/)。

    【讨论】:

    • 我没有将它初始化为NULL,框架可以!这就是我要指出的。它将它初始化为NULL。是的,我需要按钮!我可以按照我写的方式选择几个项目,甚至包含在observerenderUI 等中。
    • 我不确定我是否跟随。我将按照我的建议使用代码编辑我的答案。
    • 我有第二个 actionBtton。根据我单击的 actionButton,将不同的 dataFrame 分配给myDf。所以是的,这是有原因的。
    • 即使我没有初始化 myDF$myData as NULLproblematicDf as NULL,也会出现该错误。尝试运行类似observe({as.matrix(x = problematicDf$test)}) 的东西。那崩溃了。据我了解,它不应该崩溃! shiny.rstudio.com/reference/shiny/latest/reactiveValues.html) “当你从中读取一个值时,调用响应式表达式会对该值产生一个响应式依赖,当你写入它时,它会通知任何依赖于该值的响应式函数”。
    • 使用 NULL 通知,导致其他需要除 NULL 之外的其他输入的函数才能工作(从我的代码selected = c(levels(myDf$myData$z)[1]) ! 中可以看到其他输入)崩溃,这似乎是一个相当无用的函数在这里。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-13
    • 2020-07-02
    • 2023-03-18
    • 1970-01-01
    • 2020-11-03
    • 2011-05-10
    • 1970-01-01
    相关资源
    最近更新 更多