我正在構建一個基於真棒R Shiny軟件包的探索性視覺應用程序。應用程序要做的一件事就是讀取實值「測量」列並顯示這些測量值的箱形圖。此外,還有一個可選的selectInput
小部件,它允許用戶選擇一個組變量來潛入。變量組基本上包含具有分類值的列的名稱,例如,性別(女性vs男性),國家(美國,加拿大等)。因此,如果從羣組selectInput
中選擇「性別」,該應用將顯示兩個箱圖,一個用於女性,另一個用於男性。R Shiny:如何在執行反應語句之前更新輸入對象
要向用戶提供集中於某些類別的靈活性,說只雌性,我想出了checkboxGroupInput
當與既choices
和selected
被初始設置爲所有類別中選擇組變量,其僅示出組變量。例如,當用戶只想看到女性的箱形圖時,他/她可以容易地取消男性的複選框和男性的箱形圖,而女性的箱形圖則保留。
繼warmoverflow的建議,這裏是一個可重複的玩具例子
# global setup
library(shiny)
library(ggplot2)
library(dplyr)
set.seed(12345)
dummy_data <- data.frame(
Value = c(rnorm(50), 2 + rnorm(50)),
Gender = c(rep('Female', 50), rep('Male', 50)),
Country = c(rep('US', 50), rep('CA', 50)),
stringsAsFactors = FALSE
)
# ui function
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
selectInput('group', 'Group',
c('Choose'='', setdiff(names(dummy_data), 'Value'))),
uiOutput('group_select')
),
mainPanel(plotOutput('box_plot'))
)
)
# server function
server <- function(input, output) {
# the group level select/unselect widget
output$group_select <- renderUI({
req(input$group)
data <- dummy_data
group_levels <- unique(data[[input$group]])
conditionalPanel(
condition = "input.group != ''",
checkboxGroupInput('group_select', input$group,
choices = group_levels, selected = group_levels)
)
})
# filter the data if group variable is selected
data_to_plot <- reactive({
data <- dummy_data
if(!(is.null(input$group) || input$group == '')) {
data <- data %>%
mutate_(group_ = input$group) %>%
filter(group_ %in% input$group_select)
} else {
data$group_ <- as.factor(rep.int(1, nrow(data)))
}
return(data)
})
# show the boxplot
output$box_plot <- renderPlot({
data <- data_to_plot()
validate(
need(!(is.null(data) || nrow(data) == 0),
'There are no data to plot!')
)
ggplot(data = data, aes(factor(group_), Value)) + geom_boxplot()
})
}
shinyApp(ui = ui, server = server)
嗯,代碼工作,但reactive
語句運行不必要的兩次,一次是當input$group
得到更新和另一個當input$group_select
得到更新,你可以看到錯誤消息「沒有要繪製的數據!」當您從組下拉列表中選擇「性別」時。所以我的問題是:有沒有辦法保證以下執行順序:
input$group
更新 - >input$group_select
得到更新 - >reactive
被(重新)既更新input$group
和input$group_select
執行
我花了幾乎整整一天尋找解決方案,沒有多大用處。
- 似乎羅傑日已經在Using sendInputMessage and receiveMessage to make shiny input objects reactive解決了這個問題。但他的方法涉及創建一個jstree,這對我來說完全是一個陌生的領域,看起來他已經從他的Github中移除了解決方案。
- 另一個可能的導致是使用
observeEvent
這裏描述(R shiny Observe running Before loading of UI and this causes Null parameters)。但是,當您取消選擇input$group_select
中的一個或多個類別時,observeEvent
會忽略它。
Roger Day指出的難點在於輸入更新函數通常不會被反應,因此(根據我的實驗和理解)比被動語句晚執行。或者,如果有辦法使輸入更新功能無效,則可以應用優先級值以期望的方式更改執行順序。
任何輸入,非常感謝!對不起,很長的描述!
替代
input$group_select
你嘗試reactiveEvent功能? –你是不是指'observeEvent'?是的,當「group_select」小部件出現時使用'observeEvent(輸入$ group_select,{to_keep < - ...; data < - data [to_keep,]})''時,我嘗試過濾數據。問題在於,當您取消選擇輸入$ group_select中的一個或多個類別時,observeEvent似乎忽略了更改。例如,當從**組**''selectInput'中選擇「性別」時,「group_select」顯示最初選中「男性」和「女性」。但是,如果用戶取消選中男性,數據不會刪除所有男性行。 – statechular
不,我的意思是一個非常類似的功能 - eventReactive –