R 中的压缩列表

发布于 2024-11-09 20:05:09 字数 895 浏览 0 评论 0原文

作为指导,我更喜欢使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

乖不如嘢 2024-11-16 20:05:09

我认为您正在寻找 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)

I think you're looking for 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.

For your example, use mapply(f, A, B)

懵少女 2024-11-16 20:05:09

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

maply 太酷了!

这是一个例子:

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 
##    "牛"    "鸡"    "猪"

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:

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 
##    "牛"    "鸡"    "猪"
冷情妓 2024-11-16 20:05:09

我认为你可以用我所说的“隐式循环”(这个名字并没有完全击中它,但无论如何)来做到这一点,考虑到你可以在 *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 函数得到你想要的东西,所以如果我错过了你的观点,我很抱歉。)

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:

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

or

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

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.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文