合并具有相同结构的列表元素。

huangapple go评论95阅读模式
英文:

Combine list elements of lists with same structure

问题

我有一个包含内部列表的列表,它们都具有相同的结构,在我的情况下,它们是字符向量。现在我想要通过一个函数(在这种情况下简单地是 c)将这些内部列表组合成一个列表。以下是一个最简单的示例:

  1. list(
  2. list(one = "a",
  3. two = "b",
  4. three = "c"),
  5. list(one = "d",
  6. two = c("e", "f"),
  7. three = "g")
  8. )

我的期望输出:

  1. list(
  2. one = c("a", "d"),
  3. two = c("b", "e", "f"),
  4. three = c("c", "g")
  5. )

我已经搜索了很长时间,有类似的问题,但我没有找到完全符合我的需求的答案。我也认为类似问题的答案相当复杂。不要误解我,当然,解决这个问题并不难,但我无法想象没有一个真正优雅的方法/一行代码来解决这个问题。最好使用 tidyverse 语法。

英文:

I have a list with inner lists that all have the same structure, in my case, they are character vectors. Now I want to have a list that combines these inner lists by a function (in this case simply c). A minimal example:

  1. list(
  2. list(one = "a",
  3. two = "b",
  4. three = "c"),
  5. list(one = "d",
  6. two = c("e", "f"),
  7. three = "g")
  8. )

My desired output:

  1. list(
  2. one = c("a", "d"),
  3. two = c("b", "e", "f"),
  4. three = c("c", "g")
  5. )

I have searched quite long and there were similar questions but I haven't found exactly what I need. I also think that the answers to similar questions were quite complicated. Don't get me wrong, of course, it's no big deal to solve this problem, but I cannot imagine that there is no really elegant way/a one liner for this. Preferably with tidyverse syntax.

答案1

得分: 5

unstack(stack(unlist(l, recursive = FALSE))) # $one # [1] "a" "d" # $two # [1] "b" "e" "f" # $three # [1] "c" "g"

英文:

Unlist 1 level, stack and unstack:

  1. unstack(stack(unlist(l, recursive = FALSE)))
  2. # $one
  3. # [1] "a" "d"
  4. #
  5. # $two
  6. # [1] "b" "e" "f"
  7. #
  8. # $three
  9. # [1] "c" "g"

答案2

得分: 3

在基本的R中,您可以使用do.callMap。在列表中,do.call特别适用于按索引将函数应用于其每个元素(例如检查do.call(\(x, y) x + y, list(c(7, 9, 2), c(6, 2, 8))))。在这种情况下,由于这是一个列表的列表,必须在其上使用一个apply*函数(如Map,它接受两个参数)来进行连接。这要求列表是对称的:

  1. l <- list(
  2. list(one = "a",
  3. two = "b",
  4. three = "c"),
  5. list(one = "d",
  6. two = c("e", "f"),
  7. three = "g")
  8. )
  9. do.call(Map, c(c, l))
  10. # $one
  11. # [1] "a" "d"
  12. #
  13. # $two
  14. # [1] "b" "e" "f"
  15. #
  16. # $three
  17. # [1] "c" "g"

tidyverse语言中,这可以使用exec来完成:

  1. library(purrr)
  2. exec(Map, !!!c(c, l))
英文:

In base R, you can use do.call with Map. In a list, do.call is particularly useful to apply a function to each of its element by index (check e.g. do.call(\(x, y) x + y, list(c(7, 9, 2), c(6, 2, 8)))). Here, since it is a list of lists, one has to use an apply* function on top (like Map, which takes two arguments) to concatenate. This required the list to be symmetric:

  1. l &lt;- list(
  2. list(one = &quot;a&quot;,
  3. two = &quot;b&quot;,
  4. three = &quot;c&quot;),
  5. list(one = &quot;d&quot;,
  6. two = c(&quot;e&quot;, &quot;f&quot;),
  7. three = &quot;g&quot;)
  8. )
  9. do.call(Map, c(c, l))
  10. # $one
  11. # [1] &quot;a&quot; &quot;d&quot;
  12. #
  13. # $two
  14. # [1] &quot;b&quot; &quot;e&quot; &quot;f&quot;
  15. #
  16. # $three
  17. # [1] &quot;c&quot; &quot;g&quot;

In tidyverse language, this can be done with exec:

  1. library(purrr)
  2. exec(Map, !!!c(c, l))

答案3

得分: 3

这是另一种方法,首先使用transpose,然后使用map包裹unlist

  1. library(purrr)
  2. map(transpose(l), unlist)

输出:

  1. $one
  2. [1] "a" "d"
  3. $two
  4. [1] "b" "e" "f"
  5. $three
  6. [1] "c" "g"
英文:

Here is another approach using first transpose and then unlist wrapped arround map:

  1. library(purrr)
  2. map(transpose(l), unlist)

output:

  1. $one
  2. [1] &quot;a&quot; &quot;d&quot;
  3. $two
  4. [1] &quot;b&quot; &quot;e&quot; &quot;f&quot;
  5. $three
  6. [1] &quot;c&quot; &quot;g&quot;

huangapple
  • 本文由 发表于 2023年3月9日 17:58:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/75682976.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定