htmltools::withtags 内的变量访问
variable access within htmltools::withtags
为什么以下不打印 "names(data)" 的第 table 个元素?该元素保持为空。有趣的是,tr 部分中的 lapply 似乎没有任何问题。
data <- data.frame(a = 1, b = 2)
htmltools::withTags(table(
class = 'display',
thead(
tr(
th(rowspan = 2, "Test1"),
th(rowspan = 2, "Test2"),
th(rowspan = 2, "Test3"),
th(colspan = 2, names(data)[1]),
th(colspan = 2, names(data)[2])
),
tr(
lapply(rep(c('Abs', 'Change'), 2), th)
)
)
))
给出:
<table class="display">
<thead>
<tr>
<th rowspan="2">Test1</th>
<th rowspan="2">Test2</th>
<th rowspan="2">Test3</th>
<th colspan="2"></th> ## Why empty???
<th colspan="2"></th> ## Why empty???
</tr>
<tr>
<th>Abs</th>
<th>Change</th>
<th>Abs</th>
<th>Change</th>
</tr>
</thead>
</table>
这是eval
和substitute
共同造成的问题。让我们看看 withTags
命令:
> htmltools::withTags
function (code)
{
eval(substitute(code), envir = as.list(tags), enclos = parent.frame())
}
<environment: namespace:htmltools>
它调用此嵌套评估框架内的代码。现在我们可以分解到有趣的部分:
> eval(substitute(names(data)[1]), envir = as.list(tags))
NULL
这就是导致 th
标签保持为空的原因。现在,为什么会发生这种情况?
> names(htmltools::tags)
[1] "a" "abbr" "address" "area" "article"
[6] "aside" "audio" "b" "base" "bdi"
[11] "bdo" "blockquote" "body" "br" "button"
[16] "canvas" "caption" "cite" "code" "col"
[21] "colgroup" "command" "data" "datalist" "dd"
[26] "del" "details" "dfn" "div" "dl"
[31] "dt" "em" "embed" "eventsource" "fieldset"
[36] "figcaption" "figure" "footer" "form" "h1"
[41] "h2" "h3" "h4" "h5" "h6"
[46] "head" "header" "hgroup" "hr" "html"
[51] "i" "iframe" "img" "input" "ins"
[56] "kbd" "keygen" "label" "legend" "li"
[61] "link" "mark" "map" "menu" "meta"
[66] "meter" "nav" "noscript" "object" "ol"
[71] "optgroup" "option" "output" "p" "param"
[76] "pre" "progress" "q" "ruby" "rp"
[81] "rt" "s" "samp" "script" "section"
[86] "select" "small" "source" "span" "strong"
[91] "style" "sub" "summary" "sup" "table"
[96] "tbody" "td" "textarea" "tfoot" "th"
[101] "thead" "time" "title" "tr" "track"
[106] "u" "ul" "var" "video" "wbr"
如您所见,data 是标签之一,因此它是包含在环境中的命令之一。现在使用这组新变量评估命令。不足为奇:
> names(htmltools::tags$data)
NULL
这就是这种奇怪行为的原因。我引用 here:
Note
substitute works on a purely lexical basis. There is no guarantee that the resulting expression makes any sense.
至于避免这种行为:命名您的data.frame data1
或任何不会被误认为html的东西就足够了标签。
为什么以下不打印 "names(data)" 的第 table 个元素?该元素保持为空。有趣的是,tr 部分中的 lapply 似乎没有任何问题。
data <- data.frame(a = 1, b = 2)
htmltools::withTags(table(
class = 'display',
thead(
tr(
th(rowspan = 2, "Test1"),
th(rowspan = 2, "Test2"),
th(rowspan = 2, "Test3"),
th(colspan = 2, names(data)[1]),
th(colspan = 2, names(data)[2])
),
tr(
lapply(rep(c('Abs', 'Change'), 2), th)
)
)
))
给出:
<table class="display">
<thead>
<tr>
<th rowspan="2">Test1</th>
<th rowspan="2">Test2</th>
<th rowspan="2">Test3</th>
<th colspan="2"></th> ## Why empty???
<th colspan="2"></th> ## Why empty???
</tr>
<tr>
<th>Abs</th>
<th>Change</th>
<th>Abs</th>
<th>Change</th>
</tr>
</thead>
</table>
这是eval
和substitute
共同造成的问题。让我们看看 withTags
命令:
> htmltools::withTags
function (code)
{
eval(substitute(code), envir = as.list(tags), enclos = parent.frame())
}
<environment: namespace:htmltools>
它调用此嵌套评估框架内的代码。现在我们可以分解到有趣的部分:
> eval(substitute(names(data)[1]), envir = as.list(tags))
NULL
这就是导致 th
标签保持为空的原因。现在,为什么会发生这种情况?
> names(htmltools::tags)
[1] "a" "abbr" "address" "area" "article"
[6] "aside" "audio" "b" "base" "bdi"
[11] "bdo" "blockquote" "body" "br" "button"
[16] "canvas" "caption" "cite" "code" "col"
[21] "colgroup" "command" "data" "datalist" "dd"
[26] "del" "details" "dfn" "div" "dl"
[31] "dt" "em" "embed" "eventsource" "fieldset"
[36] "figcaption" "figure" "footer" "form" "h1"
[41] "h2" "h3" "h4" "h5" "h6"
[46] "head" "header" "hgroup" "hr" "html"
[51] "i" "iframe" "img" "input" "ins"
[56] "kbd" "keygen" "label" "legend" "li"
[61] "link" "mark" "map" "menu" "meta"
[66] "meter" "nav" "noscript" "object" "ol"
[71] "optgroup" "option" "output" "p" "param"
[76] "pre" "progress" "q" "ruby" "rp"
[81] "rt" "s" "samp" "script" "section"
[86] "select" "small" "source" "span" "strong"
[91] "style" "sub" "summary" "sup" "table"
[96] "tbody" "td" "textarea" "tfoot" "th"
[101] "thead" "time" "title" "tr" "track"
[106] "u" "ul" "var" "video" "wbr"
如您所见,data 是标签之一,因此它是包含在环境中的命令之一。现在使用这组新变量评估命令。不足为奇:
> names(htmltools::tags$data)
NULL
这就是这种奇怪行为的原因。我引用 here:
Note
substitute works on a purely lexical basis. There is no guarantee that the resulting expression makes any sense.
至于避免这种行为:命名您的data.frame data1
或任何不会被误认为html的东西就足够了标签。