在分配 reactiveValues() 空数据帧时创建
on assignment of reactiveValues() empty dataframe created
可重现的例子:
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
。但是在我看来,这是一种不优雅的方式。
你有理由将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)
。可能不是最优雅的方式,但通常效果很好。其他方式可能包括 isolate
或 observeEvent
(默认情况下它不会对 NULL 输入作出反应)。这取决于您的应用程序的整体工作方式。
但您似乎还没有完全理解反应性和其他闪亮元素的工作原理。尝试阅读 rstudio 文章,特别是 'reactive programming' 部分 (http://shiny.rstudio.com/articles/)。
可重现的例子:
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
。但是在我看来,这是一种不优雅的方式。
你有理由将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)
。可能不是最优雅的方式,但通常效果很好。其他方式可能包括 isolate
或 observeEvent
(默认情况下它不会对 NULL 输入作出反应)。这取决于您的应用程序的整体工作方式。
但您似乎还没有完全理解反应性和其他闪亮元素的工作原理。尝试阅读 rstudio 文章,特别是 'reactive programming' 部分 (http://shiny.rstudio.com/articles/)。