lapply 在函数内创建 numericInput 时无法分配标签
lapply fails to assign label in creating numericInput within a function
Lapply with labels = names(x), returns weird shiny NULL HTML class; lapply with labels = as.character(names(x)), returns 正确的 HTML class 但没有放置标签。任何想法为什么?
代表:
library(shiny)
items <- list(
"A" = "a",
"B", = "b"
)
num_inputs <- function(items){
labels <- names(items)
temp. <- NULL
for(i in 1:length(items)){
temp. <- list(temp., numericInput(inputId = items[i],
label = labels[i],
value = 1,
min = 0,
max = 10,
step = 0.1)
)
}
return(temp.)
}
# doesn't work
num_inputs_fail <- function(items){
lapply(items, FUN = function(x){
numericInput(inputId = x,
label = as.character(names(x)),
value = 1,
min = 0,
max = 10,
step = 0.1)
})
}
attempt1 <- tagList(num_inputs(items))
attempt2 <- tagList(num_inputs_fail(items))
注意这里(只是attempt1[1]和attempt[2]的标签几乎一样,但是实际的标签少了!
<div class="form-group shiny-input-container">
<label class="control-label" for="a">A</label>
<input id="a" type="number" class="form-control" value="1" min="0" max="10" step="0.1"/>
</div>
<div class="form-group shiny-input-container">
<label class="control-label" for="a"></label>
<input id="a" type="number" class="form-control" value="1" min="0" max="10" step="0.1"/>
</div>
本页:Create dynamic number of input elements with R/Shiny
包括以下代码:
output$sliders <- renderUI({
members <- as.integer(input$members) # default 2
max_pred <- as.integer(input$max_pred) # default 5000
lapply(1:members, function(i) {
sliderInput(inputId = paste0("ind", i), label = paste("Individual", i),
min = 0, max = max_pred, value = c(0, 500), step = 100)
})
})
在 renderUI 内部,链接的 shiny 应用程序似乎正确地具有标签;但即使在 lapply 中使用 paste() 函数也无法修复它。
我的 R 版本:
"R version 3.5.1 (2018-07-02)"
我的闪亮版本:
'1.4.0'
lapply
不会将输入列表的元素与其名称映射。
根据@Ben 的建议,您可以映射 names(items)
而不是映射 items
。一个例子:
items <- list(
"A" = "a",
"B" = "b"
)
lapply(names(items), function(x) data.frame(id = x, label = items[[x]]))
# [[1]]
# id label
# 1 A a
#
# [[2]]
# id label
# 1 B b
另一种方法是使用 purrr::imap
:
purrr::imap(items, ~ data.frame(id = .y, label = .x)) # .y: name .x: value
# $A
# id label
# 1 A a
#
# $B
# id label
# 1 B b
(imap
代表"indexed map").
或purrr::imap(items, function(value, name) data.frame(id = name, label = value))
.
Lapply with labels = names(x), returns weird shiny NULL HTML class; lapply with labels = as.character(names(x)), returns 正确的 HTML class 但没有放置标签。任何想法为什么?
代表:
library(shiny)
items <- list(
"A" = "a",
"B", = "b"
)
num_inputs <- function(items){
labels <- names(items)
temp. <- NULL
for(i in 1:length(items)){
temp. <- list(temp., numericInput(inputId = items[i],
label = labels[i],
value = 1,
min = 0,
max = 10,
step = 0.1)
)
}
return(temp.)
}
# doesn't work
num_inputs_fail <- function(items){
lapply(items, FUN = function(x){
numericInput(inputId = x,
label = as.character(names(x)),
value = 1,
min = 0,
max = 10,
step = 0.1)
})
}
attempt1 <- tagList(num_inputs(items))
attempt2 <- tagList(num_inputs_fail(items))
注意这里(只是attempt1[1]和attempt[2]的标签几乎一样,但是实际的标签少了!
<div class="form-group shiny-input-container">
<label class="control-label" for="a">A</label>
<input id="a" type="number" class="form-control" value="1" min="0" max="10" step="0.1"/>
</div>
<div class="form-group shiny-input-container">
<label class="control-label" for="a"></label>
<input id="a" type="number" class="form-control" value="1" min="0" max="10" step="0.1"/>
</div>
本页:Create dynamic number of input elements with R/Shiny
包括以下代码:
output$sliders <- renderUI({
members <- as.integer(input$members) # default 2
max_pred <- as.integer(input$max_pred) # default 5000
lapply(1:members, function(i) {
sliderInput(inputId = paste0("ind", i), label = paste("Individual", i),
min = 0, max = max_pred, value = c(0, 500), step = 100)
})
})
在 renderUI 内部,链接的 shiny 应用程序似乎正确地具有标签;但即使在 lapply 中使用 paste() 函数也无法修复它。
我的 R 版本: "R version 3.5.1 (2018-07-02)"
我的闪亮版本: '1.4.0'
lapply
不会将输入列表的元素与其名称映射。
根据@Ben 的建议,您可以映射 names(items)
而不是映射 items
。一个例子:
items <- list(
"A" = "a",
"B" = "b"
)
lapply(names(items), function(x) data.frame(id = x, label = items[[x]]))
# [[1]]
# id label
# 1 A a
#
# [[2]]
# id label
# 1 B b
另一种方法是使用 purrr::imap
:
purrr::imap(items, ~ data.frame(id = .y, label = .x)) # .y: name .x: value
# $A
# id label
# 1 A a
#
# $B
# id label
# 1 B b
(imap
代表"indexed map").
或purrr::imap(items, function(value, name) data.frame(id = name, label = value))
.