2016-10-12 23 views
1

我在數據中爲各個客戶ID的多個時間段創建三種類型的變量。這些新變量包括價格向量的總和,價格向量的均值以及日期向量中連續日期之間的平均差異。Data.table:通過各種數據子集動態創建變量並通過變量x進行分組,對最終結果進行子集

使用data.table,我循環了多個時間段,在每個時間段內對數據進行子集化,並計算各個客戶ID的變量。這些變量中的每一個都是隨着我在時間段內循環而動態命名的。就目前而言,這些變量正在被正確計算。

這裏是我陷入困境的地方:在計算完所有這些變量後,我希望將數據子集包括新聚合變量以及每個客戶的最近購買價格和日期元素。

我認爲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個時間段之間的任何地方循環。要計算的期數可能會發生變化,因此我的方法是動態創建新變量。

回答

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] 
+1

@Frank是的,你是對的。謝謝 – akrun

+0

看起來不錯!我想知道爲什麼期間3中客戶1的平均日期差異是NaN。查看'cust1_period3 <- data %>% 過濾器(%period_intervals [[3]]內的custid == 1和date%)%>% mutate(period.3.mean.diff.date = mean(as.numeric(diff(date ))))'返回1的平均日期差異? –

+0

@ToddYoung我認爲列名已互換 – akrun

相關問題