【发布时间】:2019-12-10 23:13:48
【问题描述】:
我有一个相当大的数据集,其中包含用户及其成员资格的开始和结束日期。每个会员期都有一个条目。
我有另一个数据集,它来自支持系统,它记录了用户 ID 以及每个系统的使用日期。这个数据集更大,因为每次使用都有一条记录。
我需要根据每个用户和会员期限汇总第二个并与第一个合并。
我尝试了一个用于 for 循环的函数,但对于一个非常大的数据集(她说的是几百万行),这将需要很长时间。
编辑:连接或合并将不起作用,因为这里第一帧中的每个 ID 都有多个范围(开始日期和结束日期之间)。每个范围都分配了一个编号。 (会员期间)第二个数据框有日期和 ID,问题是通过将每个 ID 和日期与第一帧中的日期范围进行比较来找到每个 ID 和日期的会员期间。
这里是代码,以及模拟数据集和我想在最后实现的目标:
ids <- c(rep("id1", 5), rep("id2", 5), rep("id3", 5))
#
stdates <- c("2015-08-01", "2016-08-01", "2017-08-01", "2018-08-01", "2019-08-01",
"2013-05-07", "2014-05-07", "2015-05-07", "2016-05-07", "2017-05-07",
"2011-02-13", "2013-02-13", "2015-02-13", "2016-02-13", "2017-02-13")
#
endates <- c("2016-07-31", "2017-07-31", "2018-07-31", "2019-07-31", "2020-07-31",
"2014-05-06", "2015-05-06", "2016-05-06", "2017-05-06", "2018-05-06",
"2013-02-12", "2015-02-12", "2016-02-12", "2017-02-12", "2018-02-12")
#
# First dataset:
df <- data.table(id = ids,
stdate = stdates,
endate = endates)
#
df <- df %>%
arrange(id, desc(endate))
#
# Add the membership period number for each user:
setDT(df)
df[, counter := rowid(id)]
#
# Second dataset:
ids2 <- sample(df$id, 1000, replace = TRUE)
dates2 <- sample(seq(Sys.Date() - 7*365, Sys.Date() - 365, 1), 1000)
#
df2 <- data.table(id = ids2,
dateticket = dates2)
#
# Function
counterFunc <- function(d2, d1) {
d2$groupCounter <- NA
for (i in 1:nrow(d2)) {
crdate <- d2$dateticket[i]
idtemp <- d2$id[i]
dtemp <- d1 %>%
filter(id == idtemp) %>%
data.table()
dtemp[, drcode := ifelse(crdate >= stdate & crdate <= endate, 1, 0)]
if (length(unique(dtemp$drcode)) == 2) {
dtempgc <- dtemp[drcode == 1]$counter
d2$groupCounter[i] <- dtempgc
}
if (length(unique(dtemp$drcode)) != 2) {
d2$groupCounter[i] <- 0
}
print(i)
}
return(d2)
}
#
# The result I want to get without a for loop:
df2gc <- counterFunc(df2, df)
#
【问题讨论】:
-
使用data.table non-equi join ...
-
不是连接问题。这是一个查找问题。
-
您通过连接解决了查找问题...
-
这里的查找是一个范围,而不是一个可以被“合并”使用的明确值。我真的看不出,在这种情况下如何应用联接。 @Zeiram 提供了一个可以正常工作的答案,但不适用于 5M 行的数据集。该问题类似于 IP 范围内的 IP 查找。
标签: r date datatable grouping lookup