我有两个df
d1 <- data_frame(name=c('Mike','Carl','Joe', 'Mike'),
id=c(1,2,NA,1),
id2=c('a',NA,'c','a'),
dateT=as.Date('2017-05-01','2017-05-01','2017-05-01','2016-05-01'))
# A tibble: 4 x 4
name id id2 dateT
<chr> <dbl> <chr> <date>
1 Mike 1 a 2017-05-01
2 Carl 2 <NA> 2017-05-01
3 Joe NA c 2017-05-01
4 Mike 1 a 2016-05-01
d2 <- data_frame(value=c(T, T, F, T,F),
id=c(1,2,3,1,4),
id2=c('a','b','c','a','d'),
dateT=as.Date('2017-05-01','2017-05-01','2017-05-01', '2016-05-01','2016-05-01'))
# A tibble: 5 x 4
value id id2 dateT
<lgl> <dbl> <chr> <date>
1 TRUE 1 a 2017-05-01
2 TRUE 2 b 2017-05-01
3 FALSE 3 c 2017-05-01
4 TRUE 1 a 2016-05-01
5 FALSE 4 d 2016-05-01
我正在尝试加入d2
d1
dateT
对id
和date
或 id2
和{{ 1}}取决于哪一个可用。
最后,我希望得到d2的所有记录(它们是否匹配),并附上d1中与d2匹配的所有列。
到目前为止我所拥有的是
d2 %>%
inner_join(d1, by=c('id'='id', 'dateT'='dateT'))
# A tibble: 5 x 6
value id id2.x dateT name id2.y
<lgl> <dbl> <chr> <date> <chr> <chr>
1 TRUE 1 a 2017-05-01 Mike a
2 TRUE 2 b 2017-05-01 Carl <NA>
3 FALSE 3 c 2017-05-01 <NA> <NA>
4 TRUE 1 a 2016-05-01 Mike a
5 FALSE 4 d 2016-05-01 <NA> <NA>
有两个问题:
我只想从name
附加d1
,因为在我的情况下,id2.y
始终会成为id2.x
的一部分(我只想保留) id2.x
因为它总是最完整的。我知道我可以稍后删除列,但我想知道dplyr是否有任何功能只能保留第一个数据帧中存在重复列名的列
id2
is.na(id)==T
醇>
预期输出如下:
# A tibble: 5 x 6
value id id2 dateT name
<lgl> <dbl> <chr> <date> <chr>
1 TRUE 1 a 2017-05-01 Mike
2 TRUE 2 b 2017-05-01 Carl
3 FALSE 3 c 2017-05-01 Joe
4 TRUE 1 a 2016-05-01 Mike
5 FALSE 4 d 2016-05-01 <NA>
答案 0 :(得分:1)
尝试:
library(dplyr)
d1 <- data_frame(name=c('Mike','Carl','Joe', 'Mike'),
id=c(1,2,NA,1),
id2=c('a',NA,'c','a'),
dateT=as.Date(c('2017-05-01','2017-05-01','2017-05-01','2016-05-01')))
# add combine-"c" !!
d2 <- data_frame(value=c(T, T, F, T,F),
id=c(1,2,3,1,4),
id2=c('a','b','c','a','d'),
dateT=as.Date(c('2017-05-01','2017-05-01','2017-05-01', '2016-05-01','2016-05-01')))
# add combine-"c" !!
left_join(d2,
d1 %>%
select(name, id, dateT) %>%
rename(name1=name),
by=c("id", "dateT")) %>%
left_join(d1 %>%
select(name, id2, dateT) %>%
rename(name2=name),
by=c("id2", "dateT")) %>%
transmute(value, id, id2, dateT,
name=ifelse(is.na(name1),name2,name1))
答案 1 :(得分:1)
这个怎么样?
# first join by id, dropping id2
join1 = select(d1, -id2) %>%
inner_join(d2, ., by=c("dateT", "id"))
# now take what couldn't be joined with id,
# drop id, join by id2, + left join to keep the remainder
join2 = d2 %>%
anti_join(d1, by=c("dateT", "id")) %>%
left_join(select(d1, -id), by=c("dateT", "id2"))
bind_rows(join1, join2)
# A tibble: 5 x 5
value id id2 dateT name
<lgl> <dbl> <chr> <date> <chr>
1 TRUE 1 a 2017-05-01 Mike
2 TRUE 2 b 2017-05-01 Carl
3 TRUE 1 a 2016-05-01 Mike
4 FALSE 4 d 2016-05-01 <NA>
5 FALSE 3 c 2017-05-01 Joe
请注意,只有当id2
为id
时,此代码才会在id
加入失败时尝试使用NA
。
坦率地说,我的方法需要三个连接,所以在一个庞大的数据集上,重新编码id
变量可能会更快 - 但如果不知道它在数据中意味着什么,这很难做到。