【问题标题】:data.table merge produces extra columns [R]data.table 合并产生额外的列 [R]
【发布时间】:2014-08-11 13:38:09
【问题描述】:

下面我定义了一个尺寸为 12x5 的主数据集。我把它分成四个data.tables,我想合并它们。 data.tables 之间没有行 ID 重叠,并且某些列名重叠。当我合并它们时,merge() 无法识别列名匹配,并为每个 data.table 中的每一列创建新列。最终合并的 data.table 应该是 12x5,但它是 12x7。我认为data.table的merge()中的all=TRUE命令可以解决这个问题。

library(data.table)

a <- data.table(id = c(1, 2, 3),  C1 = c(1, 2, 3))
b <- data.table(id = c(4, 5, 6),  C1 = c(1, 2, 3),  C2 = c(2, 3, 4))
c <- data.table(id = c(7, 8, 9),  C3 = c(5, 2, 7))
d <- data.table(id = c(10, 11, 12),  C3 = c(8, 2, 3), C4 = c(4, 6, 8))

setkey(a, "id")
setkey(b, "id")
setkey(c, "id")
setkey(d, "id")

final <- merge(a, b,  all = TRUE)
final <- merge(final, c,  all = TRUE)
final <- merge(final, d,  all = TRUE)

names(final)
dim(final)  #outputs correct numb of rows, but too many columns

【问题讨论】:

    标签: r merge data.table


    【解决方案1】:

    问题在于您使用“合并”功能的方式。 data.table 包中的“合并”功能默认通过“它们之间的共享键列”合并两个数据表。假设您像这样创建“a”和“b”数据表:

    library(data.table)
    a <- data.table(id = c(1, 2, 3),  C1 = c(1, 2, 3))
    b <- data.table(id = c(4, 5, 6),  C1 = c(1, 2, 3),  C2 = c(2, 3, 4))
    setkey(a, "id")
    setkey(b, "id")
    

    'a' 会变成这样:

       id C1
    1:  1  1
    2:  2  2
    3:  3  3
    

    'b' 会变成这样:

       id C1 C2
    1:  4  1  2
    2:  5  2  3
    3:  6  3  4
    

    现在,让我们先试试你的代码:

    merge(a, b,  all = TRUE)
    

    这是结果:

       id C1.x C1.y C2
    1:  1    1   NA NA
    2:  2    2   NA NA
    3:  3    3   NA NA
    4:  4   NA    1  2
    5:  5   NA    2  3
    6:  6   NA    3  4
    

    这是因为“merge”函数仅将“id”字段(数据表“a”和“b”之间的共享键)作为合并列,同时将所有非共享列添加到结果中数据表。现在让我们尝试指定要合并的列:

    merge(a, b, by=c("id","C1"), all = TRUE)
    

    现在结果将是:

       id C1 C2
    1:  1  1 NA
    2:  2  2 NA
    3:  3  3 NA
    4:  4  1  2
    5:  5  2  3
    6:  6  3  4
    

    同样适用于您调用的其他合并函数。所以试试这个:

    final <- merge(a, b, by=c("id","C1"), all = TRUE)
    final <- merge(final, c, by="id", all = TRUE)  #here you don't necessarily need to specify by...
    final <- merge( final, d, by=c("id","C3"),all=TRUE)
    
    dim(final)
    [1] 12  5
    

    【讨论】:

    • 这是否适用于两个data.tables有很多列的场景?我们是否需要将所有列的名称插入到by 字段中?
    • 是的。在 R 中调用 ?data.table::merge 并查看参数部分,在“by”下它描述了默认的合并列。实际上有一个我不推荐的技巧,或者在使用它时要小心。诀窍是将数据表“a”的所有列设置为其键,并为“b”做同样的事情。如果您的数据表有大量列,您可以这样做: setkeyv(a, names(a)); setkeyv(b,名称(b));合并(a, b, all=TRUE)
    • @cherrypoppindaddies 为什么不改用:merge(a, b, by = intersect(names(a), names(b)))?
    • 当然!对于这种情况,您的方法是最好的。但是,有时我可能不想按所有匹配的列加入,而是想选择其中的一些。
    猜你喜欢
    • 2021-10-19
    • 2022-06-17
    • 2020-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-22
    相关资源
    最近更新 更多