R блестящая передача, реагирующая на выбор selectInput
в блестящем приложении (от RStudio), на сервер сторона, у меня есть реактивный, который возвращает список переменных, разбирая содержимое textInput
. Список переменных, используется в selectInput
и/или updateSelectInput
.
я не могу заставить его работать. Есть предложения?
я сделал две попытки. Первый подход заключается в использовании реакционноспособных outVar
непосредственно в selectInput
. Второй подход заключается в использовании реакционноспособных outVar
на updateSelectInput
. Ни завод.
сервер.R
shinyServer(
function(input, output, session) {
outVar <- reactive({
vars <- all.vars(parse(text=input$inBody))
vars <- as.list(vars)
return(vars)
})
output$inBody <- renderUI({
textInput(inputId = "inBody", label = h4("Enter a function:"), value = "a+b+c")
})
output$inVar <- renderUI({ ## works but the choices are non-reactive
selectInput(inputId = "inVar", label = h4("Select variables:"), choices = list("a","b"))
})
observe({ ## doesn't work
choices <- outVar()
updateSelectInput(session = session, inputId = "inVar", choices = choices)
})
})
пользовательский интерфейс.R
shinyUI(
basicPage(
uiOutput("inBody"),
uiOutput("inVar")
)
)
некоторое время назад я отправил тот же вопрос в shiny-discuss, но он вызвал мало интереса, поэтому я спрашиваю снова, с извинениями,https://groups.google.com/forum#!тема / блестящие-обсуждение/e0MgmMskfWo
изменить 1
@Ramnath любезно опубликовал решение, которое, похоже, работает, обозначено Изменить 2 по ним. Но это решение не решает проблему, потому что textinput
на ui
сторона вместо server
сторона, как это в моей проблеме. Если я сдвину textinput
второго редактирования Рамната в server
сторона, проблема возникает снова, а именно: ничего не показывает и RStudio падает. Я нашел эту обертку!--20--> на as.character
проблема исчезает.
Изменить 2
в дальнейшем обсуждении, Ramnath показал мне, что проблема возникает, когда сервер пытается применить динамическую функцию outVar
прежде чем его аргументы будут возвращены textinput
. Решение сначала проверить, является ли .
Проверка наличия аргументов является важным аспектом создания блестящего приложения, так почему же я об этом не подумал? Да, но я, должно быть, сделал что-то не так! Учитывая сколько времени я потратил на эту проблему, это горький опыт. Я покажу после кода, как проверьте существование.
Ниже приведен код Ramnath с textinput
перешли к server
стороне. Он разбивает RStudio, поэтому не пытайтесь сделать это дома. (Я использовал его обозначение)
library(shiny)
runApp(list(
ui = bootstrapPage(
uiOutput('textbox'), ## moving Ramnath's textinput to the server side
uiOutput('variables')
),
server = function(input, output){
outVar <- reactive({
vars <- all.vars(parse(text = input$text)) ## existence check needed here to prevent a crash
vars <- as.list(vars)
return(vars)
})
output$textbox = renderUI({
textInput("text", "Enter Formula", "a=b+c")
})
output$variables = renderUI({
selectInput('variables2', 'Variables', outVar())
})
}
))
способ, которым я обычно проверяю существование, таков:
if (is.null(input$text) || is.na(input$text)){
return()
} else {
vars <- all.vars(parse(text = input$text))
return(vars)
}
Ramnath короче:
if (!is.null(mytext)){
mytext = input$text
vars <- all.vars(parse(text = mytext))
return(vars)
}
оба, кажется, работают, но я буду делать это по-Рамнат с этого момента: возможно, несбалансированный кронштейн в моей конструкции ранее помешал мне сделать проверку работа? Проверка рамната более прямая.
наконец, я хотел бы отметить пару вещей о моих попытках отладки.
в моем отладочном поиске я обнаружил, что есть возможность "ранжировать" приоритет "выходов" на стороне сервера, который я исследовал в попытке решить мою проблему, но не работал, так как проблема была в другом месте. Тем не менее, это интересно знать и, кажется, не очень хорошо известно в это время:
outputOptions(output, "textbox", priority = 1)
outputOptions(output, "variables", priority = 2)
в этом квесте Я также пробовал try
:
try(vars <- all.vars(parse(text = input$text)))
это было довольно близко, но все же не исправить.
первое решение, на которое я наткнулся, было:
vars <- all.vars(parse(text = as.character(input$text)))
я полагаю, было бы интересно узнать, почему это сработало: это потому, что это достаточно замедляет вещи? это потому что as.character
"ждет" для input$text
быть не-null?
3 ответов
вам нужно использовать renderUI
на стороне сервера для динамических UIs. Вот минимальный пример. Обратите внимание, что второе раскрывающееся меню является реактивным и настраивается на набор данных, выбранный в первом. Код должен быть понятным, если вы имели дело с shiny раньше.
runApp(list(
ui = bootstrapPage(
selectInput('dataset', 'Choose Dataset', c('mtcars', 'iris')),
uiOutput('columns')
),
server = function(input, output){
output$columns = renderUI({
mydata = get(input$dataset)
selectInput('columns2', 'Columns', names(mydata))
})
}
))
правка. Другое решение с использованием updateSelectInput
runApp(list(
ui = bootstrapPage(
selectInput('dataset', 'Choose Dataset', c('mtcars', 'iris')),
selectInput('columns', 'Columns', "")
),
server = function(input, output, session){
outVar = reactive({
mydata = get(input$dataset)
names(mydata)
})
observe({
updateSelectInput(session, "columns",
choices = outVar()
)})
}
))
EDIT2: измененный пример использования parse
. В этом приложении введенная текстовая формула используется для динамического заполнения выпадающего меню ниже со списком переменных.
library(shiny)
runApp(list(
ui = bootstrapPage(
textInput("text", "Enter Formula", "a=b+c"),
uiOutput('variables')
),
server = function(input, output){
outVar <- reactive({
vars <- all.vars(parse(text = input$text))
vars <- as.list(vars)
return(vars)
})
output$variables = renderUI({
selectInput('variables2', 'Variables', outVar())
})
}
))
насколько я могу судить, проблема в том, что input$inBody
не получить character
хотя selectInput
функция имеет значение character
как значение, а именно value = "a+b+c"
. Поэтому решение заключается в том, чтобы обернуть input$inBody
на as.character
следующие работы:
на observe
подход с updateSelectInput
:
observe({
input$inBody
vars <- all.vars(parse(text=as.character(input$inBody)))
vars <- as.list(vars)
updateSelectInput(session = session, inputId = "inVar", choices = vars)
})
на reactive
подход с selectInput
:
outVar <- reactive({
vars <- all.vars(parse(text=as.character(input$inBody)))
vars <- as.list(vars)
return(vars)
})
output$inVar2 <- renderUI({
selectInput(inputId = "inVar2", label = h4("Select:"), choices = outVar())
})
Edit: я отредактировал мой вопрос с объяснением, основанным на отзывы Ramnath по. Рамнат объяснил проблему и предоставил лучшее решение, которое я даю в качестве редактирования моего вопроса. Я сохраню этот ответ, но он не заслуживает голосов.
сервер.R
### This will create the dynamic dropdown list ###
output$carControls <- renderUI({
selectInput("cars", "Choose cars", rownames(mtcars))
})
## End dynamic drop down list ###
## Display selected results ##
txt <- reactive({ input$cars })
output$selectedText <- renderText({ paste("you selected: ", txt() ,sep="") })
## End Display selected results ##
ui.R
uiOutput("carControls"),
br(),
textOutput("selectedText")