R中的压缩列表

时间:2011-05-26 22:18:37

标签: r plyr lapply

作为指导,我更喜欢使用lapply或* ply(来自plyr)在列表元素上应用函数,而不是显式迭代它们。但是,当我必须一次处理一个列表时,这很有效。当函数接受多个参数时,我通常会进行一个循环。

我想知道是否有可能拥有一个更清洁的结构,仍然具有功能性。一种可能的方法是定义一个类似于Python的函数zip(x,y),它接受输入列表,并返回一个列表,其第i个元素是list(x,y),然后将该函数应用于这个清单。但我的问题是我是否使用最干净的方法。我并不担心性能优化,而是清晰/优雅。

以下是天真的例子。

        A <- as.list(0:9)
        B <- as.list(0:9)
        f <- function(x, y) x^2+y

        OUT <- list()
        for (n in 1:10) OUT[[n]] <- f(A[[n]], B[[n]])
        OUT
        [[1]]
        [1] 0

        [[2]]
        [1] 2

        ...

这是拉链示例(可以扩展到任意参数):

zip <- function(x, y){
    stopifnot(length(x)==length(y))
    z <- list()
    for (i in seq_along(x)){
        z[[i]] <- list(x[[i]], y[[i]]) 
    }
    z
}
E <- zip(A, B)

lapply(E, function(x) f(x[[1]], x[[2]]))

[[1]]
[1] 0

[[2]]
[1] 2

 ...

3 个答案:

答案 0 :(得分:27)

我认为你正在寻找mapply

   ‘mapply’ is a multivariate version of ‘sapply’.  ‘mapply’ applies
     ‘FUN’ to the first elements of each ...  argument, the second
     elements, the third elements, and so on.  Arguments are recycled
     if necessary.

答案 1 :(得分:1)

我认为你可以用我称之为“隐式循环”(这个名称并没有完全击中它,但无论如何)来做到这一点,考虑到你可以遍历*apply内的向量:

OUT <- lapply(1:10, function(x) (A[[x]]^2 + B[[x]]))

OUT <- lapply(1:10, function(x) f(A[[x]], B[[x]]))

请注意,您还可以使用vapply(或'sapply`)进行输出管理(例如,如果您不想要列表)。

(顺便说一句,我没有通过zip功能得到你想要的东西,所以我很抱歉,如果我错过了你的观点。)

答案 2 :(得分:1)

我今天遇到了类似的问题。在学习了功能mapply的用法之后,我现在知道如何解决它。

mapply真酷!

以下是一些示例作为备忘录:

en = c("cattle", "chicken", "pig")
zh = c("牛",      "鸡",      "猪")

dict <- new.env(hash = TRUE)
Add <- function(key, val) dict[[key]] <- val

mapply(Add, en, zh)
##  cattle chicken     pig 
##    "牛"    "鸡"    "猪" 

END。