【发布时间】:2020-11-20 21:11:14
【问题描述】:
我有一个大型数据集,其中包含多年来位于县的个人。每年,一些人搬到不同的县或离开数据集,新的人加入。 我想计算每年和第一年留在同一县的人数。这是我发现最接近这项任务的问题(没有按县进行额外分组):Month-over-month Customer Retention Rate in R
这是数据集的简化版本:
dt <- setDT(data.frame(ID = rep(c('a', 'b', 'c', 'd', 'a', 'c', 'd', 'e', 'c', 'e', 'f'),2),
CTY = rep(c(1, 2), each = 11),
YEAR = rep(c(1,1,1,1,2,2,2,2,3,3,3),2)))
到目前为止,我的解决方案依赖于循环
x =matrix(NA, 2,3)
y =matrix(NA, 2,3)
for (i in 1:2) {
for (j in 1:3) {
x[i,j] = ifelse(j == 1, NA, sum(dt[CTY == i & YEAR == j, ID] %in% dt[CTY == i & YEAR == j-1, ID] == T))
y[i,j] = ifelse(j == 1, NA, sum(dt[CTY == i & YEAR == 1, ID] %in% dt[CTY == i & YEAR == j, ID] == T))
}
}
加入后送什么
colnames(x) <- unique(dt$YEAR)
rownames(x) <- unique(dt$CTY)
x <- reshape2::melt(x)
names(x) <- c("CTY", "YEAR", "stayed")
x <- x[order(x$CTY),]
colnames(y) <- unique(dt$YEAR)
rownames(y) <- unique(dt$CTY)
y <- reshape2::melt(y)
names(y) <- c("CTY", "YEAR", "stayed2")
y <- y[order(y$CTY),]
dt <-dt[x, on = c("CTY", "YEAR")]
dt <-dt[y, on = c("CTY", "YEAR")]
dt
# ID CTY YEAR stayed stayed2
# 1: a 1 1 NA NA
# 2: b 1 1 NA NA
# 3: c 1 1 NA NA
# 4: d 1 1 NA NA
# 5: a 1 2 3 3
# 6: c 1 2 3 3
# 7: d 1 2 3 3
# 8: e 1 2 3 3
# 9: c 1 3 2 1
# 10: e 1 3 2 1
# 11: f 1 3 2 1
# 12: a 2 1 NA NA
# 13: b 2 1 NA NA
# 14: c 2 1 NA NA
# 15: d 2 1 NA NA
# 16: a 2 2 3 3
# 17: c 2 2 3 3
# 18: d 2 2 3 3
# 19: e 2 2 3 3
# 20: c 2 3 2 1
# 21: e 2 3 2 1
# 22: f 2 3 2 1
这是正确的决赛桌,但它需要对循环输出进行操作,这似乎是不必要的;总而言之,这是可行的,但它笨重且缓慢。 我已经尝试过 data.table 和 dplyr 解决方案,但似乎无法成功。
【问题讨论】:
-
根据你的循环代码没有得到预期的输出
-
如果您能更详细地描述您正在尝试的计算,将会有所帮助。
stayed的年留存率和stayed2从一开始就一直存在吗?尽管您的输出仍处于ID级别,但指标是在CTY:YEAR级别计算的,对吗?也许您可以编辑您的示例数据,以便stayed的预期结果与stayed2不同 - 如果逻辑应该不同但结果应该相同,则更难以有效测试。跨度> -
@GregorThomas 您的解释是正确的。刚刚编辑以更改 stay 和 stay2 的结果。
-
@AndreC 是正确的预期输出
-
@akrun 是正确的。我意识到措辞并不清楚。我会编辑。
标签: r dplyr data.table