【问题标题】:Iterating over separate lists in R迭代R中的单独列表
【发布时间】:2011-04-12 00:28:37
【问题描述】:

我在 R 中有很多变量,都是列表类型

a100 = list()
a200 = list()
# ...
p700 = list()

每个变量都是一个复杂的数据结构:

a200$time$data # returns 1000 x 1000 matrix

现在,我想依次将代码应用于每个变量。但是,由于 R 不支持按引用传递,我不确定该怎么做。

我的一个想法是创建一个包含所有这些列表的大列表,即,

biglist = list()
biglist[[1]] = a100
...

然后我可以遍历 biglist:

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"

【问题讨论】:

    标签: r list loops


    【解决方案1】:

    要并行遍历列表,您可以使用 mapply,它将获取并行列表,然后以锁步方式遍历它们。此外,在函数式语言中,您应该发出所需的对象,而不是在函数调用中修改数据结构。

    您应该使用 sapply、apply、lapply 等函数系列。

    吉姆

    【讨论】:

    • 感谢吉姆的想法。我怎样才能使用 lapply,并且仍然修改原始列表?例如,如果我做了lapply(biglist, function(x){x$newstuff = "profit"; x}),那么原来的biglist 就不会被修改,不是吗?每个x 只会输出到屏幕上,不会保存在任何地方?
    • Jim - 在考虑了更多之后,我认为您发出对象而不是修改对象的建议是黄金。将我的代码构造为a100 = computeStuff(a100) 比我想到的所有复杂性要好得多。感谢您的建议。
    【解决方案2】:

    jimmyb 说的很对。 lapplysapply 专门设计用于处理列表。所以他们也会和你的大名单一起工作。你不应该忘记在嵌套函数中返回对象:一个例子:

    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 通过值传递,因此您有多个漫游数据副本。如果您使用非常大的列表,您可能希望通过使用assignget 分别处理每个变量来尝试降低内存使用量。以下被认为是糟糕的编码,但有时可能需要避免内存问题:

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-12
      • 2019-06-26
      • 2023-04-08
      • 2021-06-20
      • 2022-11-04
      • 2013-01-24
      • 2021-02-07
      相关资源
      最近更新 更多