R 中的压缩列表
作为指导,我更喜欢使用 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
...
As a guideline I prefer apply functions on elements of a list using lapply or *ply (from plyr) rather than explicitly iterating through them. However, this works well when I have to process one list at a time. When the function takes multiple arguments, I usually do a cycle.
I was wondering if it's possible to have a cleaner construct, still functional in nature. One possible approach could be to define a function similar to Python, zip(x,y), which takes the input lists, and returns a list, whose i-th element is list(x, y), and then apply the function to this list. But my question is whether I am using the cleanest approach or not. I am not worried about performance optimization, but rather clarity/elegance.
Below is the naive example.
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
...
And here is the zipped example (which could be extended to arbitrary arguments):
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
...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我认为您正在寻找
mapply
:对于您的示例,请使用
mapply(f, A, B)
I think you're looking for
mapply
:For your example, use
mapply(f, A, B)
我今天遇到了类似的问题。在学习了 func
maply
的用法之后,我现在知道如何解决它了。maply
太酷了!这是一个例子:
I came across a similar problem today. And after learning the usage of the func
mapply
, I know how to solve it now.mapply
is so cool!!Here is an examples:
我认为你可以用我所说的“隐式循环”(这个名字并没有完全击中它,但无论如何)来做到这一点,考虑到你可以在
*apply
中循环向量:或
注意然后您还可以使用
vapply
(或“sapply”)进行输出管理(即,如果您不需要列表)。(顺便说一句,我没有通过
zip
函数得到你想要的东西,所以如果我错过了你的观点,我很抱歉。)I think you could do this with what I call an 'implicit loop' (this name does not hit it fully, but whatever), taking into account that you can loop over vectors within
*apply
:or
Note that you then could also use
vapply
(or 'sapply`) for output managing (i.e. if you don't want a list).(by the way, I am not getting what you want with the
zip
function, so I am sorry, if I missed your point.)