【问题标题】:How to match elements of two list in R considering the order of data frames考虑到数据帧的顺序,如何匹配 R 中两个列表的元素
【发布时间】:2013-11-21 02:13:40
【问题描述】:

大家好,我正在使用 R 中的两个数据框列表。我想解决一个小问题,我在每个列表中都有相同数量的数据框,并且每个列表都位于相同的位置。我的两个列表的 dput 版本是下一个:

list1=structure(list(a1 = structure(list(a1 = c("001", "002", "003"
), b1 = c(12, 13, 12)), .Names = c("a1", "b1"), row.names = c(NA, 
-3L), class = "data.frame"), a2 = structure(list(a1 = c("005", 
"006", "009"), b1 = c(12, 16, 16)), .Names = c("a1", "b1"), row.names = c(NA, 
-3L), class = "data.frame"), a3 = structure(list(a1 = c("011", 
"012", "053"), b1 = c(2, 3, 12)), .Names = c("a1", "b1"), row.names = c(NA, 
-3L), class = "data.frame")), .Names = c("a1", "a2", "a3"))

list2=structure(list(b1 = structure(list(d1 = c("001", "002", "003"
), c1 = c("A", "B", "C")), .Names = c("d1", "c1"), row.names = c(NA, 
-3L), class = "data.frame"), b2 = structure(list(d1 = c("005", 
"006", "009"), c1 = c("D", "E", "F")), .Names = c("d1", "c1"), row.names = c(NA, 
-3L), class = "data.frame"), b3 = structure(list(d1 = c("011", 
"012", "053"), c1 = c("G", "H", "I")), .Names = c("d1", "c1"), row.names = c(NA, 
-3L), class = "data.frame")), .Names = c("b1", "b2", "b3"))

我想将list1 中的所有数据框与list2 中它们各自的数据框相匹配,考虑到list1 中元素的变量a1list2 中元素的变量d1 之间的匹配就像每个数据帧中的一个 ID,通过这个匹配,我会将c1 变量从分配在list2 中的每个数据帧添加到list1 中的数据帧。我想获得一个类似这样的新列表:

list.final

$a1

a1 b1 c1
001 12  A
002 13  B
003 12  C 

$a2

a1 b1 c1
005 12  D
006 16  E
009 16  F

$a3
a1 b1 c1
011  2  G
012  3  H
053 12  I

我正在尝试构建一个函数来进行匹配,但它非常复杂,因为我只对单个列表有一些了解,在这里我必须处理两个可以包含 20 多个数据框的列表。如果我有一个函数,我会使用plyr 中的llply 函数来创建新列表,但我找不到解决方案。谢谢。

【问题讨论】:

    标签: r


    【解决方案1】:

    这是mapply 解决方案:

    list.final <- mapply(merge, list1, list2, 
                                by.x = "a1", by.y = "d1", SIMPLIFY = FALSE)
    list.final 
    # $a1
    #    a1 b1 c1
    # 1 001 12  A
    # 2 002 13  B
    # 3 003 12  C
    # 
    # $a2
    #    a1 b1 c1
    # 1 005 12  D
    # 2 006 16  E
    # 3 009 16  F
    # 
    # $a3
    #    a1 b1 c1
    # 1 011  2  G
    # 2 012  3  H
    # 3 053 12  I
    

    【讨论】:

      【解决方案2】:

      merge 看起来是最简单的解决方案,并且可能是我用于解决如此小问题的解决方案。无论如何,这是data.table 的解决方案。

      library(data.table)
      join_function = function( df1, df2 ) {
        dt1 = data.table(l1,key="a1")
        dt2 = data.table(l2,key="d1")
        dt1[dt2,]
      }
      Map(join_function, list1, list2)
      

      现在解释一下。我将问题分解为一一比较每个列表中的元素。为了进行比较,我创建了函数join_function。这些行

      dt1 = data.table(l1,key="a1")
      dt2 = data.table(l2,key="d1")
      

      创建data.table 对象,可以将其视为具有附加功能的data.frames。每个data.table 中的key 对进行连接至关重要。当dt1dt2 要加入时,它们会通过它们的键进行比较。如果dt1 中的一行和dt2 中的一行具有相同的键,则将这两行的列合并。所有这些工作都在简单的代码中完成

      dt1[dt2,]
      

      好的。这样就解决了两个data.frames 的连接问题。剩下的唯一事情就是对两个列表中的每一对数据框进行连接。这可以通过Map 函数来完成。这实际上多次应用一个函数(Map 的第一个参数中提供的函数。每个函数调用的参数在 Map 调用的第二个和第三个参数中提供。这可能比你想要的要多,但我刚刚弄清楚如何使用data.tables,并认为这样的解释可能会有所帮助。

      【讨论】:

      • Map 实际上是 mapply 的包装器,因此您已将 table-merge 的“by”参数转换为“key”分配。很好地证明了data.table[i, ] 和基础merge 的同源性。
      猜你喜欢
      • 2015-08-06
      • 2015-04-18
      • 2017-08-16
      • 2016-06-12
      • 2021-11-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-08
      相关资源
      最近更新 更多