【问题标题】:Combine/merge lists by elements names按元素名称组合/合并列表
【发布时间】:2013-09-03 12:59:51
【问题描述】:

我有两个列表,其元素的名称部分重叠,我需要将它们逐个元素合并/组合成一个列表:

> lst1 <- list(integers=c(1:7), letters=letters[1:5],
                words=c("two", "strings"))
> lst2 <- list(letters=letters[1:10], booleans=c(TRUE, TRUE, FALSE, TRUE),
                words=c("another", "two"), floats=c(1.2, 2.4, 3.8, 5.6))

> lst1
$integers
[1] 1 2 3 4 5 6 7

$letters
[1] "a" "b" "c" "d" "e"

$words
[1] "two"     "strings"

> lst2
$letters
 [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"

$booleans
[1]  TRUE  TRUE FALSE  TRUE

$words
[1] "another" "two"    

$floats
[1] 1.2 2.4 3.8 5.6

我尝试使用mapply,它基本上按索引组合两个列表(即:“[[”),而我需要按名称组合它们(即:“$”)。此外,由于列表具有不同的长度,因此应用了回收规则(结果相当不可预测)。

> mapply(c, lst1, lst2)
$integers
 [1] "1" "2" "3" "4" "5" "6" "7" "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"

$letters
[1] "a"     "b"     "c"     "d"     "e"     "TRUE"  "TRUE"  "FALSE" "TRUE" 

$words
[1] "two"     "strings" "another" "two"    

$<NA>
 [1] 1.0 2.0 3.0 4.0 5.0 6.0 7.0 1.2 2.4 3.8 5.6

Warning message:
In mapply(c, lst1, lst2) :
  longer argument not a multiple of length of shorter

如你所想,我正在寻找的是:

$integers
[1] 1 2 3 4 5 6 7

$letters
[1] "a" "b" "c" "d" "e" "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"

$words
[1] "two"     "strings"   "another" "two"

$booleans
[1]  TRUE  TRUE FALSE  TRUE

$floats
[1] 1.2 2.4 3.8 5.6

有什么方法可以实现吗? 谢谢!

【问题讨论】:

    标签: r list merge element named


    【解决方案1】:

    我将添加我自己的基于tapply 函数的解决方案。

    lst1 <- list(integers=c(1:7), letters=letters[1:5],
                   words=c("two", "strings"))
    lst2 <- list(letters=letters[1:10], booleans=c(TRUE, TRUE, FALSE, TRUE),
                   words=c("another", "two"), floats=c(1.2, 2.4, 3.8, 5.6))
    
    binded <- c(lst1, lst2) # and for list of lists Reduce("c", list(lst1, lst2))
    
    tapply(binded, names(binded), function(x) unlist(x, FALSE, FALSE)) # double false for better performance
    

    【讨论】:

      【解决方案2】:

      flodel's answertidyverse 用户的更新:

      list1 <- list(integers=c(1:7), letters=letters[1:5],
                     words=c("two", "strings"))
      list2 <- list(letters=letters[1:10], booleans=c(TRUE, TRUE, FALSE, TRUE),
                     words=c("another", "two"), floats=c(1.2, 2.4, 3.8, 5.6))
      
      input_list <- list(list1, list2, list1, list2)
      

      我们希望为输出列表中的每个元素精确地复制原始所需的输出两次。使用map2reduce,我们可以比涉及do.callmapplylapply 的基本R 解决方案更清晰地实现这一点。首先,我们使用c() 声明一个通过命名元素组合两个列表的函数,然后我们通过reduce 在输入列表上调用我们的函数:

      library(purrr)
      
      cat_lists <- function(list1, list2) {  
      
        keys <- unique(c(names(list1), names(list2)))
        map2(list1[keys], list2[keys], c) %>% 
          set_names(keys)  
      
      }
      
      combined_output <- reduce(input_list, cat_lists)
      

      这给了我们想要的东西:

      > combined_output
      
      #> $integers
      #>  [1] 1 2 3 4 5 6 7 1 2 3 4 5 6 7
      #> 
      #> $letters
      #>  [1] "a" "b" "c" "d" "e" "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "a" "b"
      #> [18] "c" "d" "e" "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"
      #> 
      #> $words
      #> [1] "two"     "strings" "another" "two"     "two"     "strings" "another"
      #> [8] "two"    
      #> 
      #> $booleans
      #> [1]  TRUE  TRUE FALSE  TRUE  TRUE  TRUE FALSE  TRUE
      #> 
      #> $floats
      #> [1] 1.2 2.4 3.8 5.6 1.2 2.4 3.8 5.6
      

      【讨论】:

        【解决方案3】:

        我也用grep,不知道是更好,最差,还是等价的!​​p>

        l_tmp <- c(lst1, lst2, lst1)
        keys = unique(names(l_tmp))
        l = sapply(keys, function(name) {unlist(l_tmp[grep(name, names(l_tmp))])})
        

        【讨论】:

          【解决方案4】:

          你可以这样做:

          keys <- unique(c(names(lst1), names(lst2)))
          setNames(mapply(c, lst1[keys], lst2[keys]), keys)
          

          对任意数量的列表进行泛化需要do.calllapply 的混合:

          l <- list(lst1, lst2, lst1)
          keys <- unique(unlist(lapply(l, names)))
          setNames(do.call(mapply, c(FUN=c, lapply(l, `[`, keys))), keys)
          

          【讨论】:

            猜你喜欢
            • 2014-06-23
            • 1970-01-01
            • 2013-09-17
            • 1970-01-01
            • 2014-06-08
            • 2021-11-29
            • 1970-01-01
            • 2014-04-17
            相关资源
            最近更新 更多