作为指导,我更喜欢使用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
...
答案 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。