在group_by之后连接表

时间:2015-12-07 10:17:34

标签: r left-join dplyr

我想在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)对我来说真的很方便

2 个答案:

答案 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评论,您可以首先交叉加入而不是数据x1A和数据x2B中的唯一值然后在数据集NA上执行反连接时使用B进行更新

CJ(x1 = A$x1, x2 = B$x2, unique = TRUE)[!B, x2 := NA, on = c("x1", "x2")][]