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>

这是evalsubstitute共同造成的问题。让我们看看 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的东西就足够了标签。