我在R中有很多变量,所有类型列表
a100 = list()
a200 = list()
# ...
p700 = list()
每个变量都是一个复杂的数据结构:
a200$time$data # returns 1000 x 1000 matrix
现在,我想依次将代码应用于每个变量。但是,由于R不支持pass-by-reference,我不知道该怎么做。
我的一个想法是创建所有这些列表的大清单,即
biglist = list()
biglist[[1]] = a100
...
然后我可以遍历大名单:
for (i in 1:length(biglist)){
biglist[[i]]$newstuff = "profit"
# more code here
}
最后,在循环之后,向后移动,以便现有代码(使用变量名称)仍然有效:
a100 = biglist[[1]]
# ...
问题是:有没有更好的方法来迭代一组命名列表?我有一种感觉,我做的事情非常糟糕。有没有更容易的东西,比如:
# FAKE, Idealized code:
foreach x in (a100, a200, ....){
x$newstuff = "profit"
}
a100$newstuff # "profit"
答案 0 :(得分:1)
要并行遍历列表,您可以使用mapply,它将采用并行列表,然后以锁定步骤遍历它们。此外,在函数式语言中,您应该发出所需的对象,而不是在函数调用中修改数据结构。
你应该使用sapply,apply,lapply,...系列函数。
吉姆
答案 1 :(得分:1)
jimmyb是对的。 lapply
和sapply
专门用于列表。所以他们也会与你的biglist一起工作。您不应该忘记在嵌套函数中返回对象:示例:
X <- list(A=list(A1=1:2,A2=3:4),B=list(B1=5:6,B2=7:8))
lapply(X,function(i){
i$newstuff = "profit"
return(i)
})
现在正如你所说,R通过值传递,因此你有多个漫游数据副本。如果你使用非常大的列表,你可能想要通过使用assign
和get
分别处理每个变量来尝试降低内存使用量。以下被认为是错误的编码,但有时可能需要避免内存故障:
A <- X[[1]] ; B <- X[[2]] #make the data
list.names <- c("A","B")
for (i in list.names){
tmp <- get(i)
tmp$newstuff <- "profit"
assign(i,tmp)
rm(tmp)
}
确保您清楚地了解此代码的含义,因为您正在全球环境中工作。如果您需要更频繁地执行此操作,则可能需要使用环境:
my.env <- new.env() # make the environment
my.env$A <- X[[1]];my.env$B <- X[[2]] # put vars in environment
for (i in list.names){
tmp <- get(i,envir=my.env)
tmp$newstuff <- "profit"
assign(i,tmp,envir=my.env)
rm(tmp)
}
my.env$A
my.env$B