基于变量名称 R 命名列表元素

Name list elements based on variable names R

我想即时向空列表中添加元素。列表中的每个元素都应根据一组值会变化的变量自动命名。

但是,我似乎无法找到一种在不出错的情况下动态命名列表元素的方法。考虑以下示例:

L <- list()

var1 <- "wood"
var2 <- 1.0
var3 <- "z4"

varname <- paste(var1, as.character(var2), var3, sep="_")

# This works fine:
L$"wood_1_z4" <- c(0,1)
L$"wood_1_z4"
0 1

# This doesn't!!
L$paste(var1, as.character(var2), var3, sep="_") <- c(0,1)
Error in L$paste(var1, as.character(var2), var3, sep = "_") <- c(0, 1) : 
  invalid function in complex assignment

# Ths doesn't either ... 
L$eval(parse(text = "varname")) <- c(0,1)
Error in L$eval(parse(text = "varname")) <- c(0, 1) : 
target of assignment expands to non-language object

有办法吗?

您不能使用 <- 运算符分配给 paste()(我相信 eval() 函数也是如此)。相反,您需要使用 [[ 运算符或使用 names() 函数。您可以这样做:

L <- list()
var1 <- "wood"
var2 <- 1.0
var3 <- "z4"
varname <- paste(var1, as.character(var2), var3, sep="_")

# Using [[
L[[varname]] <- c(0,1)

> L
$wood_1_z4
[1] 0 1

# Using names()
L[[1]] <- c(0,1)
names(L)[1] <- varname

> L
$wood_1_z4
[1] 0 1

一种更有效的方法可能是使用既创建值又命名列表元素的函数,或者甚至只创建值的函数 - 如果您随后使用 sapply,您可以命名每个列表元素都使用函数调用中的参数和 USE.NAMES 选项。

一般而言,当列表的最终大小和结构不为人所知时,R 并没有针对随着时间的推移不断增长的列表进行优化。虽然可以做到,但更 "R-ish" 的方法是提前弄清楚结构。

另一种方法是使用 stats 包中的包装器 setNames(),如下所示:

var1 <- "wood"
var2 <- 1.0
var3 <- "z4"
varname <- paste(var1, as.character(var2), var3, sep="_")

L <- setNames(list(c(0, 1)), varname)

> L
$wood_1_z4
[1] 0 1 

使用 `names<-` 中缀运算符作为 return 命名列表的普通函数。然后使用 c() 将其与列表 L 连接。这一行可用于继续按要求向 L 'on the fly' 添加元素。

L <- list()
var1 <- "wood"
var2 <- 1.0
var3 <- "z4"
varname <- paste(var1, as.character(var2), var3, sep="_")

L <- c(L, `names<-`(list(c(0, 1)), varname))

L
#> $wood_1_z4
#> [1] 0 1