更快的unique()来比较两个数据帧中的键

时间:2019-03-12 19:04:56

标签: r

尝试对大数据进行以下分析时,我遇到以下问题:

我有两个数据框A和B,它们具有相同的主键(在多列上),但是数据框A还带有一个日期变量。

我现在想检查是否在数据框B中也有一个条目,是否针对数据框A中的所有唯一实体。我使用以下功能进行此操作:

checkMissing <- function(A, B, primary_key) {
  A <- unique(A[,primary_key])
  B <- unique(B[,primary_key])
  return(A[!A %in% B,])
}

事实证明,当A获取越来越多的数据时,唯一的部分太慢了(我检查了15MN行之类的东西,在我的机器上花了大约30秒)。

是否有一种更聪明的方法可以在不使用dplyr的情况下检查B中是否缺少实体? (基数R会很完美,但是data.table也可以)

以下是可复制的示例:

library(tictoc)
checkMissing <- function(A, B, primary_key) {
  tic("making data unique")
  A <- unique(A[,primary_key])
  B <- unique(B[,primary_key])
  toc()
  return(A[!A %in% B,])
}
# creating the dummy key data

ID1 <- 250000
ID2 <- seq(1,ID1/100,1)
ID3 <- seq(1,ID1/10000,1)

tmp <- data.frame("ID1" = seq(1,ID1,1),
                  "ID2" = sample(ID2, ID1, replace = TRUE),
                  "ID3" = sample(ID3, ID1, replace = TRUE)
)

#creating the date sequence
dates <- data.frame("date" = seq.Date(as.Date("2019-01-01"),as.Date("2019-02-28"),1))

#cross join to get data frame A
df.A <- merge(dates,tmp,by=NULL)

# create data frame B
df.B <- unique(df.A[,c("ID1","ID2","ID3")])

tic("overall time")
df.result <- checkMissing(df.A,df.B,c("ID1","ID2","ID3"))
toc()

谢谢! 斯蒂芬

1 个答案:

答案 0 :(得分:0)

joran在他的评论中指出-data.table中的反连接实现更快:

setDT(df.A)[!df.B, on = c("ID1","ID2","ID3")]

在我的测试数据执行时间从30-35秒减少到不到2秒。

尽管仍然对更快的基本R版本感兴趣,但这是正确的答案。

最佳 斯蒂芬