我有以下数据帧:
a <- data.frame(Test=1:4,
TestA=5:6)
> a
Test TestA
1 1 5
2 2 6
3 3 5
4 4 6
b <- data.frame(TEST=1:10,
TestB=11:20)
> b
TEST TestB
1 1 11
2 2 12
3 3 13
4 4 14
5 5 15
6 6 16
7 7 17
8 8 18
9 9 19
10 10 20
我想将它们组合起来,以便结果看起来像这样:
Test TestA TEST TestB
1 1 5 1 11
2 2 6 2 12
3 3 5 3 13
4 4 6 4 14
5 0 0 5 15
6 0 0 6 16
7 0 0 7 17
8 0 0 8 18
9 0 0 9 19
10 0 0 10 20
也就是说,要与填充零的不匹配行合并。
我坚信存在一个简单的解决方案,如果可以使用dplyr
,那就很好了。
答案 0 :(得分:1)
有了data.table,您可以
b
中预先填充0,然后a
的喜欢...
# input
a <- data.frame(Test=1:4, TestA=5:6)
b <- data.frame(TEST=1:10, TestB=11:20)
library(data.table)
setDT(a); setDT(b)
# prefill
b[, c("Test", "TestA") := 0L]
# update join
b[a, on=.(TEST = Test), c("Test", "TestA") := .(i.Test, i.TestA)]
TEST TestB Test TestA
1: 1 11 1 5
2: 2 12 2 6
3: 3 13 3 5
4: 4 14 4 6
5: 5 15 0 0
6: 6 16 0 0
7: 7 17 0 0
8: 8 18 0 0
9: 9 19 0 0
10: 10 20 0 0
这将修改b
而不是创建新表。这适用于您的示例,但是如果您需要“完全连接”(其中b
在最终表中没有您想要的完整行集合),则另一个答案会更好。
另一方面,如果您的表具有不希望用零填充的真实NA,则这是比前几个答案更好的方法(覆盖所有NA,不仅覆盖由于行不匹配而导致的NA)。表的联接/合并/组合)。
要归纳为更多列,请定义default
值的列表...
# input
a <- data.frame(Test=1:4, TestA=5:6)
b <- data.frame(TEST=1:10, TestB=11:20)
library(data.table)
setDT(a); setDT(b)
defaults = list(Test = 0L, TestA = 0L)
new_cols = names(defaults)
# prefill defaults
b[, (new_cols) := defaults]
# update join
b[a, on=.(TEST = Test), (new_cols) := mget(sprintf("i.%s", new_cols))]
答案 1 :(得分:1)
您可以使用软件包sqldf
:
library(sqldf)
res <- sqldf("SELECT a.*, b.* FROM b LEFT JOIN a on a.test = B.test")
res[is.na(res)] <- 0
res
# Test TestA TEST TestB
# 1 1 5 1 11
# 2 2 6 2 12
# 3 3 5 3 13
# 4 4 6 4 14
# 5 0 0 5 15
# 6 0 0 6 16
# 7 0 0 7 17
# 8 0 0 8 18
# 9 0 0 9 19
# 10 0 0 10 20
或者仅使用SQL
,将功能coalesce
用作@G。格洛腾迪克提到:
sqldf("SELECT coalesce(a.Test, 0) Test, coalesce(a.TestA, 0) TestA, b.* FROM b LEFT JOIN a using(test)")
答案 2 :(得分:0)
要重复“测试”列并希望用0而不是NA有点不寻常,但正是您所要求的是:
library(dplyr)
b$Test <- b$TEST
c <- full_join(a,b, by="Test")
c$Test[is.na(c$TestA)] <-0
c$TestA[is.na(c$TestA)] <-0
答案 3 :(得分:0)
df <- merge(a, b, by = 0, all = TRUE,sort = FALSE)[-1]
df[is.na(df)] <- 0
df
Test TestA TEST TestB
1 1 5 1 11
2 2 6 2 12
3 3 5 3 13
4 4 6 4 14
5 0 0 5 15
6 0 0 6 16
7 0 0 7 17
8 0 0 8 18
9 0 0 9 19
10 0 0 10 20
答案 4 :(得分:0)
您可以使用merge()
合并两个数据帧。
df<-merge(x=a,y=b,by.x="Test",by.y = "TEST",all= T)
以上内容产生:
Test TestA TestB
1 1 5 11
2 2 6 12
3 3 5 13
4 4 6 14
5 5 NA 15
6 6 NA 16
7 7 NA 17
8 8 NA 18
9 9 NA 19
10 10 NA 20
如果要将Test
和TEST
分开,则可以为两者创建一个ID列,并用该ID变量替换by.x
和by.y
。
要将NA替换为0,可以使用df$TestA[is.na(TestA)]<-0
。如果您想同时保留Test
和Test
,则与TEST
相同。
答案 5 :(得分:0)
# example datasets
a <- data.frame(Test=1:4,
TestA=5:6)
b <- data.frame(TEST=1:10,
TestB=11:20)
library(dplyr)
a %>%
mutate(TEST = Test) %>% # duplicate Test column and give the name TEST
full_join(b, by="TEST") %>% # full join
mutate_at(vars(Test, TestA), ~coalesce(.,0L)) # replace NAs with 0s for those two variables
# Test TestA TEST TestB
# 1 1 5 1 11
# 2 2 6 2 12
# 3 3 5 3 13
# 4 4 6 4 14
# 5 0 0 5 15
# 6 0 0 6 16
# 7 0 0 7 17
# 8 0 0 8 18
# 9 0 0 9 19
# 10 0 0 10 20
您还可以使用mutate_all(~coalesce(.,0L))
,但是如果您知道它们仅存在于这两列中,则无需查找所有NA。