【问题标题】:Logical Merging of Dataframes数据帧的逻辑合并
【发布时间】:2013-01-28 12:13:13
【问题描述】:

我有两个 data.frames,其中一个包含一式三份进行的许多实验的特定顺序(DF1 设计表);另一个包含这些实验的结果(一式三份,DF2 结果表)。第一个数据帧的实验顺序是随机的,结果表的顺序不同。

DF1 的前六列包含实验因素,例如温度、试剂当量等...结果表 DF2 也有相同的六列以及包含实验结果的其他列,例如产率、各种试剂的转化率等...

表格因行数而异。结果表比系列零件设计表少三行。

如何合并这两个表,以便将结果附加到设计中,以使设计表中的实验参数与实验表中的相应结果相匹配。

DF1

T1  A1  B1
T2  A1  B1
T1  A2  B1
T2  A2  B1
T1  A1  B2
T2  A1  B2
T1  A2  B2
T2  A2  B2

但一式三份。

DF2

T1  A2  B2  1
T1  A2  B1  3
T2  A2  B1  3
T1  A1  B1  1
T2  A1  B2  2
T2  A2  B2  2
T2  A1  B1  2

再次一式三份,注意少了一行。请注意,结果列比显示的多。

至于所有这些工作的重点:我正在研究是否可以将包 RcmdrPlugin.DoE 应用于一些真实数据。

至于我尝试过的......好吧,我考虑过将 sapply、cbind 和 ifelse 与逻辑函数一起使用

sapply(
DF3 <- ifelse( DF1[,1] == DF2[,1] | DF1[,2] == DF2[,2] | DF2[,3] == DF2[,3],
cbind(DF1, DF2[,3]), NA)
)

我对这段代码中的 NA 有疑问。但在我到达 NA 之前,我发现我有一个参数 'FUN' is missing error。

我认为我要么离题要么非常接近答案,但两者中的哪一个。谁能指出我正确的方向,好吗?

编辑 ... 我将标题更改为 A、B、C 和 D 的七行数据样本,这些数据是两个 data.frames 共有的。

      run.no run.no.std.rp Block.ccd   A     B C     D
C0.17      1         C0.17         0 400 147.5 5 2.675
C0.7       2          C0.7         0 450 120.0 2 4.000
C0.6       3          C0.6         0 350 175.0 2 4.000
C0.3       4          C0.3         0 450 120.0 8 4.000
C0.4       5          C0.4         0 350 120.0 8 4.000
C0.16      6         C0.16         0 350 120.0 2 1.350
C0.15      7         C0.15         0 450 120.0 2 1.350

另一个 data.frame 具有标题 A、B、C 和 D 以及包含产量、转化率和其他结果的列。我需要第一个 data.frame 与最后标记的 yield 等完全相同。

【问题讨论】:

    标签: r


    【解决方案1】:

    data.table 包(允许 x[y] 语法)使这项工作变得异常简单。假设df1df2 是你的data.frames:

    require(data.table)
    dt1 <- data.table(df1, key=c("V1","V2","V3"))
    dt2 <- data.table(df2, key=c("V1","V2","V3"))
    dt2[dt1]
    
    #    V1 V2 V3 V4
    # 1: T1 A1 B1  1
    # 2: T1 A1 B2 NA
    # 3: T1 A2 B1  3
    # 4: T1 A2 B2  1
    # 5: T2 A1 B1  2
    # 6: T2 A1 B2  2
    # 7: T2 A2 B1  3
    # 8: T2 A2 B2  2
    

    给你想要的结果。

    编辑:我使用了您编辑的数据,它似乎有效。

    df1 <- structure(list(V1 = structure(c(1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L), 
                         .Label = c("T1", "T2"), class = "factor"), 
                     V2 = structure(c(1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L), 
                     .Label = c("A1", "A2"), class = "factor"), 
                     V3 = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L), 
                     .Label = c("B1", "B2"), class = "factor")), 
                     .Names = c("V1", "V2", "V3"), 
                     class = "data.frame", row.names = c(NA, -8L))
    
    df2 <- structure(list(V1 = structure(c(1L, 1L, 2L, 1L, 2L, 2L, 2L), 
                          .Label = c("T1", "T2"), class = "factor"), 
                          V2 = structure(c(2L, 2L, 2L, 1L, 1L, 2L, 1L), 
                          .Label = c("A1", "A2"), class = "factor"), 
                          V3 = structure(c(2L, 1L, 1L, 1L, 2L, 2L, 1L), 
                          .Label = c("B1", "B2"), class = "factor"), 
                          run.no = 1:7, 
                          run.no.std.rp = structure(c(3L, 7L, 6L, 4L, 5L, 2L, 1L), 
                          .Label = c("C0.15", "C0.16", "C0.17", "C0.3", "C0.4", "C0.6", "C0.7"), 
                          class = "factor"), 
                          Block.ccd = c(0L, 0L, 0L, 0L, 0L, 0L, 0L), 
                          A = c(400L, 450L, 350L, 450L, 350L, 350L, 450L), 
                          B = c(147.5, 120, 175, 120, 120, 120, 120), 
                          C = c(5L, 2L, 2L, 8L, 8L, 2L, 2L), 
                          D = c(2.675, 4, 4, 4, 4, 1.35, 1.35)), 
                          .Names = c("V1", "V2", "V3", "run.no", "run.no.std.rp", 
                          "Block.ccd", "A", "B", "C", "D"), 
                          row.names = c("C0.17", "C0.7", "C0.6", "C0.3", "C0.4", 
                          "C0.16", "C0.15"), class = "data.frame")
    
    require(data.table)
    dt1 <- data.table(df1, key=c("V1", "V2", "V3"))
    dt2 <- data.table(df2, key=c("V1", "V2", "V3"))
    dt2[dt1]
    #    V1 V2 V3 run.no run.no.std.rp Block.ccd   A     B  C     D
    # 1: T1 A1 B1      4          C0.3         0 450 120.0  8 4.000
    # 2: T1 A1 B2     NA            NA        NA  NA    NA NA    NA
    # 3: T1 A2 B1      2          C0.7         0 450 120.0  2 4.000
    # 4: T1 A2 B2      1         C0.17         0 400 147.5  5 2.675
    # 5: T2 A1 B1      7         C0.15         0 450 120.0  2 1.350
    # 6: T2 A1 B2      5          C0.4         0 350 120.0  8 4.000
    # 7: T2 A2 B1      3          C0.6         0 350 175.0  2 4.000
    # 8: T2 A2 B2      6         C0.16         0 350 120.0  2 1.350
    

    【讨论】:

    • 我提供的示例数据可能已经完成,但是当我将代码与我拥有的数据一起使用时,我得到了一个错误。 '[.data.table'(dt2,dt1) 中的错误:typeof x.Temp (double) != typeof i.Block.ccd (integer)
    • 嗨@Arun,我建议的表有 102 行。上面的代码是将data.frame转换为data.table的唯一方法吗?
    • 嗨@Arun,我的真实数据返回,'[.data.table(dt2, dt1) 中的错误:x.'Temp' 是连接到 i.'Temp' 类型的因子列整数'。因子列必须连接到因子或字符列。'
    【解决方案2】:

    您的标题提到了“合并”,但您似乎没有尝试过merge 功能。 (或者我错过了什么?)

    这是您的前两个示例data.frames:

    DF1 <- structure(list(T1 = c("T2", "T1", "T2", "T1", "T2", "T1", "T2"
      ), A1 = c("A1", "A2", "A2", "A1", "A1", "A2", "A2"), B1 = c("B1", 
      "B1", "B1", "B2", "B2", "B2", "B2")), .Names = c("T1", "A1", 
      "B1"), class = "data.frame", row.names = c(NA, -7L))
    
    DF2 <- structure(list(T1 = c("T1", "T2", "T1", "T2", "T2", "T2"), A2 = c("A2", 
      "A2", "A1", "A1", "A2", "A1"), B2 = c("B1", "B1", "B1", "B2", 
      "B2", "B1"), X1 = c(3L, 3L, 1L, 2L, 2L, 2L)), .Names = c("T1", 
      "A2", "B2", "X1"), class = "data.frame", row.names = c(NA, -6L))
    

    以下是您使用基础 R 中的 merge 的方法。by.xby.y 参数应该包含您在两个 data.frames 中应该共有的列的名称。 all 参数表示不要删除任何“空白”,而是用 NA 填充它们。

    merge(DF1, DF2, 
          by.x = c("T1", "A1", "B1"), 
          by.y = c("T1", "A2", "B2"), 
          all = TRUE)
    #   T1 A1 B1 X1
    # 1 T1 A1 B1  1
    # 2 T1 A1 B2 NA
    # 3 T1 A2 B1  3
    # 4 T1 A2 B2 NA
    # 5 T2 A1 B1  2
    # 6 T2 A1 B2  2
    # 7 T2 A2 B1  3
    # 8 T2 A2 B2  2
    

    这是 Arun 创建的两个 data.frames 上的 merge 的结果。请注意,我们不需要指定要合并的列,因为它们具有共同的列名。

    merge(df1, df2, all = TRUE)
    #   V1 V2 V3 run.no run.no.std.rp Block.ccd   A     B  C     D
    # 1 T1 A1 B1      4          C0.3         0 450 120.0  8 4.000
    # 2 T1 A1 B2     NA          <NA>        NA  NA    NA NA    NA
    # 3 T1 A2 B1      2          C0.7         0 450 120.0  2 4.000
    # 4 T1 A2 B2      1         C0.17         0 400 147.5  5 2.675
    # 5 T2 A1 B1      7         C0.15         0 450 120.0  2 1.350
    # 6 T2 A1 B2      5          C0.4         0 350 120.0  8 4.000
    # 7 T2 A2 B1      3          C0.6         0 350 175.0  2 4.000
    # 8 T2 A2 B2      6         C0.16         0 350 120.0  2 1.350
    

    【讨论】:

    • 会试试这个并报告,@anada
    • 两个答案都适用于给出的示例数据。谢谢你的帮助。我勾选了两个答案,但默认设置只允许一个答案占上风。特别感谢 @Arun 让我注意到 data.tables。
    • 当应用于我的真实数据集时,我得到'fix.by(by.x,x)错误:'by'必须匹配列数'这是我的尝试,尝试.1
    • @user1945827,第 6-9 列和第 2、3、6、4 列的名称是什么?您可以尝试以下两种方法之一:(1) 使用列 names,就像我在示例中所做的那样; (2) 重命名每个数据集中的相关列,使其相同(也就是说,DF1 中的第 6 列应该与 DF2 中的第 2 列同名)。
    • 您的@anaanda 建议,'(1) 使用列名,正如我在示例中所做的那样,没有返回任何错误。谢谢
    猜你喜欢
    • 1970-01-01
    • 2021-04-23
    • 2022-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-15
    • 2017-02-23
    • 2018-06-20
    相关资源
    最近更新 更多