18

作为指导方针,我更喜欢使用 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

 ...
4

3 回答 3

29

我想你正在寻找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.

对于您的示例,请使用mapply(f, A, B)

于 2011-05-26T22:25:42.000 回答
4

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

mapply太酷了!!

这是一个例子:

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

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

mapply(Add, en, zh)
##  cattle chicken     pig 
##    "牛&quot;    "鸡&quot;    "猪&quot;
于 2019-01-23T10:25:34.563 回答
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(或“应用”)进行输出管理(即,如果您不想要列表)。

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

于 2011-05-26T22:31:24.417 回答