2

使用这样的基本功能:

myname<-function(z){
   nm <-deparse(substitute(z))
   print(nm)
}

我希望在遍历列表时打印(或返回)项目的名称,例如

for (csv in list(acsv, bcsv, ccsv)){
myname(csv)
}

应该打印:

acsv
bcsv
ccsv

(而不是csv)。

需要注意的是,acsv、bcsv、ccsvs都是从csvs中读入的dataframe,即

acsv = read.csv("a.csv")
bcsv = read.csv("b.csv")
ccsv = read.csv("c.csv")

编辑: 我最终使用了一些妥协。这样做的主要目标不是简单地打印框架名称 - 这是问题所在,因为它是做其他事情的先决条件。

我需要在四个格式相同的文件上运行相同的函数。然后我使用了这个语法:

for(i in 1:length(csvs)){
    cat(names(csvs[i]), "\n")
    print(nrow(csvs[[i]]))
    print(nrow(csvs[[i]][1]))
}

然后使用嵌套列表的索引,例如

print(nrow(csvs[[i]]))

它显示了每个数据帧的行数。

打印(nrow(csvs[[i]][1]))

然后为每个数据框的第一列提供一个表格。

我包括这个是因为它是这个问题的动力。我需要能够为每个正在检查的数据框标记数据。

4

2 回答 2

2

你所构造的list不再“记住”它所构造的表达式。但是您可以使用自定义构造函数:

named.list <- function(...) {
    l <- list(...)
    exprs <- lapply(substitute(list(...))[-1], deparse)
    names(l) <- exprs
    l
}

所以:

> named.list(1+2,sin(5),sqrt(3))
$`1 + 2`
[1] 3

$`sin(5)`
[1] -0.9589243

$`sqrt(3)`
[1] 1.732051

names正如 Thomas建议的那样,将此列表用作参数:

> names(mylist(1+2,sin(5),sqrt(3)))
[1] "1 + 2"   "sin(5)"  "sqrt(3)"

要了解这里发生了什么,让我们分析以下内容:

> as.list(substitute(list(1+2,sqrt(5))))
[[1]]
list

[[2]]
1 + 2

[[3]]
sqrt(5)

索引省略了第[-1]一个元素,所有剩余元素都传递给deparse,这是因为......

> lapply(as.list(substitute(list(1+2,sqrt(5))))[-1], class)
[[1]]
[1] "call"

[[2]]
[1] "call"

请注意,您不能“重构”list(...)内部调用substitute()以简单地使用l. 你明白为什么吗?

我还想知道这样的功能是否已经在无数的 R 包之一中可用。我发现威廉邓拉普的这篇文章有效地暗示了同样的方法。

于 2013-05-31T19:27:52.360 回答
1

我不知道你的数据是什么样的,所以这里是编造的:

csvs <- list(acsv=data.frame(x=1), bcsv=data.frame(x=2), ccsv=data.frame(x=3))
for(i in 1:length(csvs))
    cat(names(csvs[i]), "\n")
于 2013-05-31T19:10:28.563 回答