我有一个简单的练习:x
是一列data.frame dt
。我想制作一个闪亮的应用程序,打印出x
的平均值。如果复选框"乘以2"然后选择x
乘以2.如果不是那么旧值。
library(shiny)
dt <- data.frame(x = 1:10, y = rep(c(2,3),5))
ui <- fluidPage(
checkboxInput("myCheckbox", "multiple dt$x by 2"),
actionButton("myButton", "show result")
)
server <- function(input, output) {
i <- 0
observeEvent(input$myCheckbox,{ # if this checkbox is true then dt$x should be muiltiplied by 2
i <<- i + 1
if(i > 1){ # first call should not change dt$x
if(input$myCheckbox){
dt$x <<- dt$x * 2
}else{
dt$x <<- dt$x / 2
}
}
})
observeEvent(input$myButton,{
showNotification(paste0("Mean of dt$x is equal ", mean(dt$x)), type="default")
})
}
shinyApp(ui, server)
如何避免<<-
?这是有风险的,在我使用300行代码的更大的Shiny应用程序中,我有时会得到一个错误,表示R无法选择范围。
答案 0 :(得分:1)
在服务器函数中定义dt
的被动版本。您可以使用多个输入值来定义反应式表达式。另一种选择是设置一个reactiveValues()
对象并用观察者更新它,但我认为reactive()
表达式更适合这种情况。如果您尝试定义的值完全由当前输入值确定。如果您想使用应用程序迭代操作它,那么reactiveValues()
可能会更好。
library(shiny)
library(dplyr)
dt <- data.frame(x = 1:10, y = rep(c(2,3),5))
ui <- fluidPage(
checkboxInput("myCheckbox", "multiple dt$x by 2"),
checkboxInput("myOtherCheckbox", "set dt$x to 0"),
actionButton("myButton", "show result")
)
server <- function(input, output){
dt2 <- reactive({
mutate(dt, x = if(input$myCheckbox==TRUE){2*x} else{x}) %>%
mutate(x = if(input$myOtherCheckbox==TRUE){0}else{x}
})
observeEvent(input$myButton,{
showNotification(paste0("Mean of dt$x is equal ", mean(dt2()$x)), type="default")
})
}
shinyApp(ui, server)
答案 1 :(得分:1)
您可以使用reactiveValues
函数进行反应式编程:
library(shiny)
dt <- data.frame(x = 1:10, y = rep(c(2, 3), 5))
ui <- fluidPage(
checkboxInput("myCheckbox", "multiple dt$x by 2"),
actionButton("myButton", "show result")
)
server <- function(input, output) {
values <- reactiveValues(x = dt$x)
observeEvent(input$myCheckbox, {
if (input$myCheckbox) {
values$x <- values$x * 2
} else {
values$x <- values$x / 2
}
})
observeEvent(input$myButton, {
showNotification(paste0("Mean of dt$x is equal ", mean(values$x)), type = "default")
print(dt$x)
})
}
shinyApp(ui, server)
reactiveValues
函数返回一个用于存储被动值的对象。它允许您避免全局更改变量,这是您想要的。