首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用do.call在R中创建ui

使用do.call在R中创建ui
EN

Stack Overflow用户
提问于 2020-08-21 14:21:47
回答 2查看 385关注 0票数 3

我在看是否有可能使用do.call创建一个R闪亮的ui函数,并且不理解下面的问题。首先,如果我做一个没有do.call的基本例子.

代码语言:javascript
复制
library(shiny)

ui <- fluidPage(
  titlePanel("A title"),
  fluidRow(column(width = 12,"some content",))
)

server <- function(input, output) {}
shinyApp(ui = ui, server = server)

...then这与预期的显示"A标题“和”某些内容“的页面呈现在下面。

如果我试图使用do.call来做我认为完全相同的事情,如下所示.

代码语言:javascript
复制
library(shiny)

page_data <- c(
  titlePanel("A title"),
  fluidRow(column(width = 12,"some content",))
)
ui <- do.call(fluidPage, as.list(page_data))

server <- function(input, output) {}
shinyApp(ui = ui, server = server)

..。这样就不会呈现相同的页面。有趣的是,它没有错误地运行,显示了"A标题“,但没有显示”某些内容“。有什么想法可以解释它为什么会呈现不同的效果?还可以使用do.call类型接口实现吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-08-21 14:42:14

您可以在开始时定义一个列表而不是一个向量,因此以后不使用as.list()。但是,我不知道为什么使用list()as.list(c())不同

代码语言:javascript
复制
library(shiny)

page_data <- list(
  titlePanel("A title"),
  fluidRow(column(width = 12,"some content",))
)
ui <- do.call(fluidPage, page_data)

server <- function(input, output) {}
shinyApp(ui = ui, server = server)

编辑:,实际上,我们可以看到这两个表达式之间的一些区别:

代码语言:javascript
复制
list(
  titlePanel("A title"),
  fluidRow(column(width = 12,"some content",))
)

[[1]]
<h2>A title</h2>

[[2]]
<div class="row">
  <div class="col-sm-12">some content</div>
</div>
代码语言:javascript
复制
as.list(c(
  titlePanel("A title"),
  fluidRow(column(width = 12,"some content",))
))

[[1]]


[[2]]
<h2>A title</h2>

$name
[1] "div"

$attribs
$attribs$class
[1] "row"


$children
$children[[1]]
<div class="col-sm-12">some content</div>
票数 3
EN

Stack Overflow用户

发布于 2020-08-22 17:52:29

罪魁祸首实际上不是as.list,而是c。闪亮的UI函数不像人们想象的那样返回普通的HTML,而是返回一个shiny.tag对象(如果将多个shiny.tag对象组合在一起,则返回shiny.tag列表)。shiny.tag对象是一个列表,它包含关于所使用的HTML的名称及其子标记的信息(例如,其他标记及其内容,有关更多信息,请看这里)。当打印shiny.tag对象时,我们看到HTML代码的原因是,对于shiny.tagshiny.tag.list对象有特殊的printas.character方法。

查看fluidRow(column(width = 12,"some content"))的输出

代码语言:javascript
复制
str(fluidRow(column(width = 12,"some content")))
List of 3
 $ name    : chr "div"
 $ attribs :List of 1
  ..$ class: chr "row"
 $ children:List of 1
  ..$ :List of 3
  .. ..$ name    : chr "div"
  .. ..$ attribs :List of 1
  .. .. ..$ class: chr "col-sm-12"
  .. ..$ children:List of 1
  .. .. ..$ : chr "some content"
  .. ..- attr(*, "class")= chr "shiny.tag"
 - attr(*, "class")= chr "shiny.tag"

从内部看,这是一个清单!但是,如果打印出来的话:

代码语言:javascript
复制
print(fluidRow(column(width = 12,"some content")))
<div class="row">
  <div class="col-sm-12">some content</div>
</div>

对于titlePanel("A title")也是如此,它实际上在shiny.tag.list中生成两个shiny.tag对象。

代码语言:javascript
复制
str(titlePanel("A title"))
List of 2
 $ :List of 3
  ..$ name    : chr "head"
  ..$ attribs : Named list()
  ..$ children:List of 1
  .. ..$ :List of 3
  .. .. ..$ name    : chr "title"
  .. .. ..$ attribs : Named list()
  .. .. ..$ children:List of 1
  .. .. .. ..$ : chr "A title"
  .. .. ..- attr(*, "class")= chr "shiny.tag"
  ..- attr(*, "class")= chr "shiny.tag"
 $ :List of 3
  ..$ name    : chr "h2"
  ..$ attribs : Named list()
  ..$ children:List of 1
  .. ..$ : chr "A title"
  ..- attr(*, "class")= chr "shiny.tag"
 - attr(*, "class")= chr [1:2] "shiny.tag.list" "list"

如果将其组合为一个列表,那么单个shiny.tag对象仍然保留它们的列表结构,所以do.call(fluidPage, page_data_list)生成UI没有问题。您基本上创建了一个列表:

代码语言:javascript
复制
page_data_list <- list(
  titlePanel("A title"),
  fluidRow(column(width = 12,"some content"))
)

str(page_data_list, max.level = 1)
List of 2
 $ :List of 2
  ..- attr(*, "class")= chr [1:2] "shiny.tag.list" "list"
 $ :List of 3
  ..- attr(*, "class")= chr "shiny.tag"

然而,c试图组合列表。现有的list对象不会在新创建的列表中获得它们自己的列表,但是最高的列表级别会被合并(c基本上会追加列表):

代码语言:javascript
复制
page_data <- c(
  titlePanel("A title"),
  fluidRow(column(width = 12,"some content"))
)

str(page_data, max.level = 1)
List of 5
 $         :List of 3
  ..- attr(*, "class")= chr "shiny.tag"
 $         :List of 3
  ..- attr(*, "class")= chr "shiny.tag"
 $ name    : chr "div"
 $ attribs :List of 1
 $ children:List of 1

as.list(page_data)不会改变任何东西,因为page_data已经是一个列表了。

现在,shiny.tag对象不再具有正确的结构,do.call(fluidPage, page_data)也无法工作。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63524661

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档