我对data.table完全不熟悉,所以请耐心等待。在以下示例中,我想在我的数据集中创建两个新列:每个客户ID在两个不同时间段内的总购买价格。到目前为止,我有这个工作。
但是,在尝试对数据进行子集时,我遇到了困难。我想对数据进行分组,以便每行代表一个唯一的客户ID以及最终购买价格,最终购买日期,期间1购买价格总计以及它们的期间2购买价格总计。
我认为data.table可能会复制与每个客户对应的所有行的计算总计。但是,它仅复制与表 i 索引中指定的句点间隔对应的行中的总计。由于它不会为每个客户的所有行复制这些总计,因此我的最终dplyr块不起作用。
在第二个和第三个代码块中,我将给出最终dplyr代码的输出,然后是我想要实现的输出。
library(lubridate)
library(data.table)
library(dplyr)
data <- data.frame(custid = c(rep(1, 4), rep(2, 4), rep(1, 4), rep(2, 4)),
purchase.price = seq(1, 32, by=2),
date = seq.Date(from=as.Date("2015-01-01"), to=as.Date("2015-01-16"), by="days"))
period_intervals <- list(period_one = interval(as.Date("2015-01-01"), as.Date("2015-01-09")),
period_two = interval(as.Date("2015-01-10"), as.Date("2015-01-16")))
data <- as.data.table(data)
data <- data[order(date)]
setkey(data, custid)
data <- data[date %within% period_intervals[[1]],
period.1.price.total := sum(purchase.price),
by = custid]
data <- data[date %within% period_intervals[[2]],
period.2.price.total := sum(purchase.price),
by = custid]
data_sub <- data %>%
group_by(custid) %>%
arrange(desc(date)) %>%
filter(row_number() == 1)
目前的结果:
custid purchase.price date period.1.price.total period.2.price.total
<dbl> <dbl> <date> <dbl> <dbl>
1 31 2015-01-16 NA 112
2 23 2015-01-12 NA 63
最后,我的目标是:
custid purchase.price date period.1.price.total period.2.price.total
<dbl> <dbl> <date> <dbl> <dbl>
1 31 2015-01-16 33 112
2 23 2015-01-12 48 63
答案 0 :(得分:1)
我们可以通过使用索引
对purchase.price进行子集化来实现data[, .(period.1.total.sum = sum(purchase.price[date %within%
period_intervals[[1]]])),by = custid]
要同时创建列,我们可以使用Map
nm1 <- c('period.1. total.sum', 'period.2.total.sum')
data[, (nm1) := Map(function(x,y) sum(purchase.price[x %within% y]),
list(date), period_intervals), by = custid]
data[order(custid, -date)][,.SD[1:.N==1] , custid]
# custid purchase.price date period.1. total.sum period.2.total.sum
#1: 1 23 2015-01-12 33 63
#2: 2 31 2015-01-16 48 112
注意:&#39;总计&#39; OP创建代码未在OP的帖子中显示。