[英]Dynamic number of input widgets in shiny
I want to write an app that reads in the uploaded data, then puts enough numericInput
due to the number of unique elements in a column (the name of the columns is Big). 我想编写一个应用程序,该应用程序读取上载的数据,然后由于列中唯一元素的数量(列的名称为Big)而放置了足够的
numericInput
。 This question here helped me. 这个问题在这里帮助我。
The code is as below: 代码如下:
library(shiny)
ui <- fluidPage(
fileInput(inputId = "up","", accept = '.csv'),
uiOutput("sliders")
)
server <- function(input, output, session) {
INPUT <- reactive({
infile <- input$up
#validate(need(input$up, "Input a valid filepath."))
read.csv(infile$datapath, header = TRUE, sep = ",")
})
inVars <- reactive({
unique(INPUT()$Big)
})
output$sliders <- renderUI({
pvars <- length(inVars())
lapply(seq(pvars), function(i) {
numericInput(inputId = paste0("range", pvars[i]),label = pvars[i],value = 1)
})
})
}
shinyApp(ui = ui, server = server)
Three questions: 三个问题:
1. When I put 1.当我放
if (is.null(infile))
return(NULL)
instead of validate
, it gives me an error which looks like this: 而不是
validate
,它给了我一个错误,看起来像这样:
missing value where TRUE/FALSE needed
What should I do to get rid of this error? 我应该怎么做才能摆脱这个错误?
2. How could I add a label for each one of the numericInput
? 2.如何为每个
numericInput
添加标签?
3. How could I use the input values later? 3.以后如何使用输入值? In a
reactive
environment? 在
reactive
环境中?
Thanks 谢谢
The problem is not with the if (is.null(infile))
statement, it is with the lapply
function. 问题不在于
if (is.null(infile))
语句,而是lapply
函数。 When the Shiny app just starts, the entire server
function is executed, the length of inVars()
is 0
and the sequence seq(pvars)
will be 1
0
. 当Shiny应用程序刚刚启动时,将执行整个
server
功能, inVars()
的长度为0
,序列seq(pvars)
将为1
0
。 Then the numericInput
will fail because you are making a reference to pvars[i]
when i
is equal to 0
. 然后,
numericInput
将失败,因为当i
等于0
时,您正在引用pvars[i]
。
Below is the code that fixes the problem and also answers your questions. 以下是可解决问题并回答您问题的代码。
library(shiny)
ui <- fluidPage(
fileInput(inputId = "up","", accept = '.csv'),
uiOutput("sliders")
)
server <- function(input, output, session) {
INPUT <- reactive({
infile <- input$up
if (is.null(infile))
return(NULL)
read.csv(infile$datapath, header = TRUE, sep = ",")
})
inVars <- reactive({
unique(INPUT()$Big)
})
output$sliders <- renderUI({
pvars <- length(inVars())
if (pvars > 0) {
div(
lapply(seq(pvars), function(i) {
numericInput(inputId = paste0("range", inVars()[i]),label = inVars()[i],value = 1)
}),
actionButton("getValues", "Get values"),
tableOutput('table')
)
}
})
values <- 0
# get the values of each numericInput and store them in "values"
observeEvent(input$getValues, {
# initialize vector
values <<- rep(NA, length(inVars()))
names(values) <<- inVars()
for(k in 1:length(inVars())) {
inputName <- paste0("range", inVars()[k])
# only get a value if the numeric input exists
if (!is.null(inputName))
values[[k]] <<- input[[inputName]]
}
# show values as a table
output$table <- renderTable(data.frame(
variable = inVars(),
values))
})
}
shinyApp(ui = ui, server = server)
Update: 更新:
To test the code, use a .csv file with content like: 要测试代码,请使用内容如下的.csv文件:
num,Big
1,a
2,a
3,b
4,b
5,c
6,c
7,d
8,d
Screenshot: 截图:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.