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

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

Combine list elements of lists with same structure

问题

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

list(
  list(one = "a", 
       two = "b", 
       three = "c"), 
  list(one = "d", 
       two = c("e", "f"), 
       three = "g")
)

我的期望输出:

list(
  one = c("a", "d"),
  two = c("b", "e", "f"),
  three = c("c", "g")
)

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

list(
  list(one = "a", 
       two = "b", 
       three = "c"), 
  list(one = "d", 
       two = c("e", "f"), 
       three = "g")
  )

My desired output:

list(
  one = c("a", "d"),
  two = c("b", "e", "f"),
  three = c("c", "g")
)

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:

unstack(stack(unlist(l, recursive = FALSE)))
# $one
# [1] "a" "d"
# 
# $two
# [1] "b" "e" "f"
# 
# $three
# [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,它接受两个参数)来进行连接。这要求列表是对称的:

l <- list(
  list(one = "a", 
       two = "b", 
       three = "c"), 
  list(one = "d", 
       two = c("e", "f"), 
       three = "g")
)

do.call(Map, c(c, l))

# $one
# [1] "a" "d"
# 
# $two
# [1] "b" "e" "f"
# 
# $three
# [1] "c" "g"

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

library(purrr)
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:

l &lt;- list(
  list(one = &quot;a&quot;, 
       two = &quot;b&quot;, 
       three = &quot;c&quot;), 
  list(one = &quot;d&quot;, 
       two = c(&quot;e&quot;, &quot;f&quot;), 
       three = &quot;g&quot;)
)

do.call(Map, c(c, l))

# $one
# [1] &quot;a&quot; &quot;d&quot;
# 
# $two
# [1] &quot;b&quot; &quot;e&quot; &quot;f&quot;
# 
# $three
# [1] &quot;c&quot; &quot;g&quot;

In tidyverse language, this can be done with exec:

library(purrr)
exec(Map, !!!c(c, l))

答案3

得分: 3

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

library(purrr)

map(transpose(l), unlist)

输出:

$one
[1] "a" "d"

$two
[1] "b" "e" "f"

$three
[1] "c" "g"
英文:

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

library(purrr)

map(transpose(l), unlist)

output:

$one
[1] &quot;a&quot; &quot;d&quot;

$two
[1] &quot;b&quot; &quot;e&quot; &quot;f&quot;

$three
[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:

确定