data.table合并产生额外的列[R]

Dr.*_*rox 3 merge r data.table

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

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
Run Code Online (Sandbox Code Playgroud)

小智 5

问题在于您使用“合并”功能的方式。默认情况下,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")
Run Code Online (Sandbox Code Playgroud)

其中“ a”将是这样的:

   id C1
1:  1  1
2:  2  2
3:  3  3
Run Code Online (Sandbox Code Playgroud)

和“ b”将是这样的:

   id C1 C2
1:  4  1  2
2:  5  2  3
3:  6  3  4
Run Code Online (Sandbox Code Playgroud)

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

merge(a, b,  all = TRUE)
Run Code Online (Sandbox Code Playgroud)

结果如下:

   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
Run Code Online (Sandbox Code Playgroud)

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

merge(a, b, by=c("id","C1"), all = TRUE)
Run Code Online (Sandbox Code Playgroud)

现在的结果将是:

   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
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)