首页 > 解决方案 > 强制执行 R 中的列表项

问题描述

我在生成 html 的命名列表中有一堆闪亮的函数。我希望能够调用列表中的一个项目,并将闪亮的函数传递给调用函数(bs4Dash::bs4TabPanel()将一大块已编译的 html 传递给调用函数 - 该函数将接受任何一个。

我觉得这应该很容易,但我无法弄清楚如何正确地做到这一点:

l <- list("list_item" = list(force(tags$strong("Something something...")),
                             force(tags$strong("Something else..."))))

paste(l[["list_item"]], collapse = "")
# > "list(name = \"strong\", attribs = list(), children = list(\"Something something...\"))list(name = \"strong\", attribs = list(), children = list(\"Something else...\"))"

pasted <- lapply(l[["list_item"]], paste)
paste(pasted, collapse = "")
# > "<strong>Something something...</strong><strong>Something else...</strong>"

如果我制作“粘贴的”中间变量,它会起作用,但这似乎是不必要的黑客攻击,因为我不明白我在做什么。

更新:

starja 非常彻底的回答以非常有用的解释回答了我提出的问题。然而......原来我的问题是错误的。以防万一其他人正在寻找涉及 bs4TabPanel 的答案,它不会将 html 作为输入(我认为我之前已经这样做了)。我正在做的失败是:

arguments <- c(tabName, active, l[[list_item]])
do.call(bs4TabPanel, arguments)

在将它们交给 bs4TabPanel 之前,它正在执行 l[[list_item]] 中的函数。我需要的是:

arguments <- c(tabName, active)
do.call(bs4TabPanel, c(arguments, l[[list_item]]))

标签: rlistshiny

解决方案


看看这里发生了什么(你实际上不需要force):

l <- list("list_item" = list(tags$strong("Something something..."),
                              tags$strong("Something else...")))

每个tags$strong创建一个带有类的列表shiny.tag

str(l)
List of 1
 $ list_item:List of 2
  ..$ :List of 3
  .. ..$ name    : chr "strong"
  .. ..$ attribs : Named list()
  .. ..$ children:List of 1
  .. .. ..$ : chr "Something something..."
  .. ..- attr(*, "class")= chr "shiny.tag"
  ..$ :List of 3
  .. ..$ name    : chr "strong"
  .. ..$ attribs : Named list()
  .. ..$ children:List of 1
  .. .. ..$ : chr "Something else..."
  .. ..- attr(*, "class")= chr "shiny.tag"

帮助网站tags声明:

这些函数的结果是一个标签对象,可以使用 as.character() 进行转换。

因此,如果您使用 use as.character,列表将变为:

l_new <- lapply(l$list_item, as.character)
str(l_new)
List of 2
 $ : chr "<strong>Something something...</strong>"
 $ : chr "<strong>Something else...</strong>"

现在您可以选择一个条目或将它们粘贴在一起:

paste0(l_new, collapse = "")
[1] "<strong>Something something...</strong><strong>Something else...</strong>"

但请注意,您这样做了lapplyl$list_item因为您list_item在 html 标记中包含两个带有文本的条目。如果您有多个list_items,则需要将 s 应用于as.character您的每个条目list_item

lapply(l, function(list_item) {
  res <- lapply(list_item, as.character)
  paste0(res, collapse = "")
})

如果要使用 html,可以使用tag对象:

library(shiny)

ui <- fluidPage(
  htmlOutput("output_1")
)

server <- function(input, output,session) {
  
  l <- list("list_item" = list(tags$strong("Something something..."),
                                tags$strong("Something else...")))
  
  output$output_1 <- renderUI({
    l$list_item[[1]]
  })
}

shinyApp(ui = ui, server = server)

或者您可以生成实际的 html 并将其放入HTML函数中:

library(shiny)

ui <- fluidPage(
  htmlOutput("output_1")
)

server <- function(input, output,session) {
  
  l <- list("list_item" = list(tags$strong("Something something..."),
                                tags$strong("Something else...")))
  
  output$output_1 <- renderUI({
    HTML(as.character(l$list_item[[1]]))
  })
}

shinyApp(ui = ui, server = server)

推荐阅读