您如何获取嵌套的R列表树,并以一种可以作为代码计算的方式打印它们?
例如,假设我们有以下列表代码:spec <- list(
description="An mtcards example",
data = list(),
mark = "point",
encoding = list(
x = list(field = "wt", type="quantitative"),
y = list(field="mpg", type="quantitative"),
color = list(field="cyl", type="nominal")))
是否有一个函数f
(无论是在标准库中,还是在CRAN中的某个地方),使得f(spec)
产生一个看起来或多或少像用于定义spec
的代码的字符串,理想情况下基于行长度有相同的缩进?比如:
'list(
description="An mtcards example",
data = list(),
mark = "point",
encoding = list(
x = list(field = "wt", type="quantitative"),
y = list(field="mpg", type="quantitative"),
color = list(field="cyl", type="nominal")))'
这在其他语言中是可能的,比如JS、Python和Clojure。通常,数据结构以字面量的形式打印出来,可以由手边的语言进行计算。还有一些特殊的函数可以处理缩进(我们通常称之为"漂亮的打印")。但我不记得曾经在R中遇到过这样的东西(尽管我已经很多年没有广泛地使用它了),而且Google在提供任何东西方面被证明是无用的。
就上下文而言,现在正在考虑用其他语言生成Vega- lite/Vega示例的自动翻译(这对于Clojure EDN数据表示来说很容易),但目前尚不清楚我们将如何为vegwidget使用的R数据规范做这件事。有没有人知道我们应该怎么做,或者觉得有灵感写代码来手工完成?
谢谢!
更新有人指出,deparse
(和dput
)在这里非常接近,但它们仍然没有输出您期望在实际代码中看到的那种缩进。特别是,对于这个例子,我得到:
> dput(spec)
list(description = "An mtcards example", data = list(), mark = "point",
encoding = list(x = list(field = "wt", type = "quantitative"),
y = list(field = "mpg", type = "quantitative"), color = list(
field = "cyl", type = "nominal")))
特别是,除非必要,否则我希望在列表定义中间不要断行;color = ...
应该在它自己的线上。对于顶级list(...)
中的其他条目位于同一行,而其他条目则分开,我并不感到兴奋,但我们可能可以接受这种情况。虽然在代码文档中,我从未期望看到color = ...
列表像这样跨行分解,所以这并不能完全解决问题,除非有人有更好的解决方案。
再次感谢!
函数dput
是我们将R对象转换为文本字符串的标准方式,该字符串将在R控制台上运行时复制该对象。事实上,当在Stack Overflow上的R标签中发布问题和答案时,它经常被使用。例如:
x <- list(a = 1, b = "2")
dput(x)
#> list(a = 1, b = "2")
然而,dput
并不总是给出美观的输出。这听起来像你正在寻找的是dput
与代码美化器的组合。
Base R没有代码修饰符。除此之外,代码美观与否是非常主观的,与大多数编程语言一样,R的作者并没有规定法律代码的布局。
然而,R中有一些可以美化代码的包,这些包可以用于dput
的输出。例如,我们可以编写这样的函数:
f <- function(x) {
text_con <- textConnection("output", "w")
dput(x, text_con)
close(text_con)
formatR::tidy_source(text = output, args.newline = TRUE, width = 40)
}
这是一种美化的dput
:
f(spec)
#> list(
#> description = "An mtcards example", data = list(),
#> mark = "point", encoding = list(
#> x = list(field = "wt", type = "quantitative"),
#> y = list(field = "mpg", type = "quantitative"),
#> color = list(field = "cyl", type = "nominal")
#> )
#> )