我想在group_by操作之后在两个表上执行连接。
A <- data.frame(x1=c("a","b","c","d"))
B <- data.frame(x1=c("a","c","d","c","a"), x2=c(1,1,1,2,2))
这个想法是x2是一个ID,x1可能类似于日期,可能还有其他列的温度值。表格A
包含所有日期,B
包含实际上的日期。在没有观察的情况下,我想得到一张表格,其中包含所有带有NA的ID的所有日期。
folowwing命令生成:
> dplyr::left_join(A,B,by="x1")
x1 x2
1 a 1
2 a 2
3 b NA
4 c 1
5 c 2
6 d 1
但我想要的更像是:
x1 x2
a 1
a 2
b NA
b NA
c 1
c 2
d 1
d NA
所以我尝试了这个没有成功:
B %>% dplyr::group_by(x2) %>% dplyr::left_join(A,.data,by="x1")
如果可能的话,保持group_by(x2)
对我来说真的很方便
答案 0 :(得分:4)
执行此操作的一种方法是添加一个变量,用于计算x1
的观察次数,然后使用tidyr::complete
完成data.frame。
require(dplyr)
left_join(A, B, by="x1") %>%
# add variable "obs"
group_by(x1) %>%
mutate(obs = seq(n())) %>%
ungroup %>%
# complete the data
tidyr::complete(x1, obs) %>%
select(-obs)
来源:本地数据框[8 x 2]
## x1 x2
## (chr) (dbl)
## 1 a 1
## 2 a 2
## 3 b NA
## 4 b NA
## 5 c 1
## 6 c 2
## 7 d 1
## 8 d NA
答案 1 :(得分:3)
我想我明白你想要实现的目标。首先,您希望按x1
加入两个数据集,然后根据唯一组的数量展开数据集。这是一个可能的data.table
解决方案
library(data.table) # V 1.9.6+
# Store the number of unique ids in x2
GRPs <- uniqueN(B$x2)
# First join by x1 and then expand according to number of unique groups in x2
setDT(B)[A, .SD[c(1:.N, rep(NA, GRPs - .N))], by = x1, on = "x1"]
# x1 x2
# 1: a 1
# 2: a 2
# 3: b NA
# 4: b NA
# 5: c 1
# 6: c 2
# 7: d 1
# 8: d NA
或者针对您的具体情况的更具体的解决方案可能会更快
setDT(B)[A, if(.N < GRPs) c(x2, rep(NA, GRPs - .N)) else x2, by = x1, on = "x1"]
或者根据@Aruns评论,您可以首先交叉加入而不是数据x1
中A
和数据x2
中B
中的唯一值然后在数据集NA
上执行反连接时使用B
进行更新
CJ(x1 = A$x1, x2 = B$x2, unique = TRUE)[!B, x2 := NA, on = c("x1", "x2")][]