我在多个时间段内为我的数据中的各个客户ID创建了三种类型的变量。这些新变量包括价格向量的总和,价格向量的平均值,以及日期向量中连续日期之间的平均差异。
使用data.table,我循环遍历多个时间段,对每个时段中的数据进行子集化,并为各个客户ID计算这些变量。当I循环遍历时间段时,这些变量中的每一个都是动态命名的。目前,这些变量正在正确计算。
这就是我陷入困境的地方:在计算完所有这些变量后,我希望将数据子集化,以包含新的聚合变量以及每个客户的最新purchase.price和date元素。
我认为data.table可能会复制与每个客户对应的所有行的计算总计。但是,它仅复制与表i索引中指定的句点间隔对应的行中的总计。由于它不会为每个客户的所有行复制这些总计,因此我的最终dplyr块不起作用。
在第二个和第三个代码块中,我将给出最终dplyr代码的输出,然后是我想要实现的输出。
这个问题源于我们subsetting over fewer variables that are not being created dynamically所指出的类似问题。
library(lubridate)
library(data.table)
library(dplyr)
data <- data.frame(custid = c(rep(1, 25), rep(2, 25), rep(1, 25), rep(2, 25)),
purchase.price = seq(1, 200, by=2),
date = seq.Date(from=as.Date("2015-01-01"), to=as.Date("2015-04-10"), by="days"))
period_intervals <- list(period_one = interval(as.Date("2015-01-01"), as.Date("2015-01-30")),
period_two = interval(as.Date("2015-02-01"), as.Date("2015-02-28")),
period_three = interval(as.Date("2015-03-01"), as.Date("2015-03-31")),
period_four = interval(as.Date("2015-04-01"), as.Date("2015-04-28")))
data <- as.data.table(data)
data <- data[order(date)]
setkey(data, custid)
time_periods <- c(1:4)
for(i in time_periods[1]:max(time_periods)){
data <- data[date %within% period_intervals[[i]],
paste("period", i, "price.sum", sep="."):= sum(purchase.price),
by = custid]
data <- data[date %within% period_intervals[[i]],
paste("period", i, "price.mean", sep="."):= mean(purchase.price),
by = custid]
data <- data[date %within% period_intervals[[i]],
paste("period", i, "mean.diff.date", sep="."):= mean(as.numeric(diff(purchase.price))),
by = custid]
}
data_sub <- data %>%
group_by(custid) %>%
arrange(desc(date)) %>%
filter(row_number() == 1)
dplyr子集的当前结果(显示前7列):
custid purchase.price date period.1.price.sum period.1.price.mean period.1.mean.diff.date period.2.price.sum ...
<dbl> <dbl> <date> <dbl> <dbl> <dbl> <dbl> ...
1 2 199 2015-04-10 NA NA NA NA ...
2 1 149 2015-03-16 NA NA NA NA ...
这是我所希望的(显示前7列):
custid purchase.price date period.1.price.sum period.1.price.mean period.1.mean.diff.date period.2.price.sum ...
<dbl> <dbl> <date> <dbl> <dbl> <dbl> <dbl> ...
1 2 199 2015-04-10 625 25 2 981 ...
2 1 149 2015-03-16 275 55 2 1539 ...
注意:
在我的完整数据集中,我在10到20个时间段内循环。要计算的周期数可能会发生变化,因此我的方法是动态创建新变量。
答案 0 :(得分:2)
我们可以像上一篇文章中那样使用Map
nm1 <- sprintf("%s.%d.%s", "period", seq_along(period_intervals), "price.sum")
nm2 <- sprintf("%s.%d.%s", "period", seq_along(period_intervals), "price.mean")
nm3 <- sprintf("%s.%d.%s", "period", seq_along(period_intervals), "mean.diff.date")
data[, c(rbind(nm1, nm2, nm3)) := unlist(Map(function(x,y) {
x1 <- purchase.price[x %within% y]
list(sum(x1), mean(x1), mean(as.numeric(diff(x1))))},
list(date), period_intervals), recursive = FALSE), by = custid]
data[order(custid, -date)][,.SD[1] , custid]