2015-12-22 44 views
1

我有數據框df,包括客戶名稱,加入日期,到期日和隊列。R中的隊列數據轉換

names   dj  exp cohort 
    (fctr)  (date)  (date) (chr) 
1 Tom 2011-05-01 2011-06-22 2011-05 
2 David 2011-06-01 2011-07-19 2011-06 
3 Jack 2011-05-03 2012-01-03 2011-05 
> 

names<-c("Tom","David","Jack") 
dj<-as.Date(c("2011-05-01","2011-06-01","2011-05-03")) 
exp<-as.Date(c("2011-06-22","2011-07-19","2012-01-03")) 
df<-data.frame(names,dj,exp) 
df$cohort<-format(df$dj,"%Y-%m") 
tbl_df(df) 

和矢量DateColumns <- seq.Date(as.Date("2011/05/01"), as.Date("2015/12/1"), by = "1 month")自2011年5月1日的日曆日期2015年12月1日

從中我想檢查客戶是否在特定月份或不活躍。活動定義爲一個客戶記錄> DateColumns & DJ < = DateColumns

輸出1(正確):

names dj exp cohort    2011-05-01 2011-06-01 2011-07-01 2011-08-01 . 

Tom 2011-05-01 2011-06-22 2011-05 TRUE  TRUE  FALSE  FALSE 
David 2011-06-01 2011-07-19 2011-06 FALSE  TRUE  TRUE  FALSE 
Jack 2011-05-03 2012-01-03 2011-05 TRUE  TRUE  TRUE  TRUE .... 

下面是我寫的代碼,可惜這無法與比較兩者到期日和DJ日期欄中的日曆日期。例如,大衛在X1中應該是虛假的。那麼,我該怎麼做?

不正確的輸出

names<-c("Tom","David","Jack") 
    dj<-as.Date(c("2011-05-01","2011-06-01","2011-05-03")) 
    exp<-as.Date(c("2011-06-22","2011-07-19","2012-01-03")) 
    df<-data.frame(names,dj,exp) 
    df$cohort<-format(df$dj,"%Y-%m") 


    DateColumns <- seq.Date(as.Date("2011/05/01"), as.Date("2015/12/1"), by = "1 month") 

DateColumnvalues <- t(sapply(df$exp, function(x) x > DateColumns)) 
df2 <- data.frame(df,DateColumnvalues) 
tbl_df(df2) 

output: 
names   dj  exp cohort X1 X2 X3 X4 X5 X6 
    (fctr)  (date)  (date) (chr) (lgl) (lgl) (lgl) (lgl) (lgl) (lgl) 
1 Tom 2011-05-01 2011-06-22 2011-05 TRUE TRUE FALSE FALSE FALSE FALSE 
2 David 2011-06-01 2011-07-19 2011-06 **TRUE** TRUE TRUE FALSE FALSE FALSE 
3 Jack 2011-05-03 2012-01-03 2011-05 TRUE TRUE TRUE TRUE TRUE TRUE 
Variables not shown: X7 (lgl), X8 (lgl), X9 (lgl), X10 (lgl), X11 (lgl), 
    X12 (lgl), X13 (lgl), X14 (lgl), X15 (lgl), X16 (lgl), X17 (lgl), X18 
    (lgl), X19 (lgl), X20 (lgl), X21 (lgl), X22 (lgl), X23 (lgl), X24 (lgl), 
    X25 (lgl), X26 (lgl), X27 (lgl), X28 (lgl), X29 (lgl), X30 (lgl), X31 
    (lgl), X32 (lgl), X33 (lgl), X34 (lgl), X35 (lgl), X36 (lgl), X37 (lgl), 
    X38 (lgl), X39 (lgl), X40 (lgl), X41 (lgl), X42 (lgl), X43 (lgl), X44 
    (lgl), X45 (lgl), X46 (lgl), X47 (lgl), X48 (lgl), X49 (lgl), X50 (lgl), 
    X51 (lgl), X52 (lgl), X53 (lgl), X54 (lgl), X55 (lgl), X56 (lgl) 
> 

注:X1是 「2011-05-01」 和X2 = 「2011-06-01」 等表示日曆月

其次,我想要改造這個數據「相對」基於加入和隊列的月份進行彙總。例如,如果客戶「迪克」於2015年1月加入,並且將於2015年12月到期,則他的M0應設爲真,但M0應視爲2015年1月而非日曆月。

Names dj exp cohort      M0 M1 M2 M3 till M55 
Dick 2015-01-11 2015-12-10 2015-01  T T T T 
Tom 2011-05-01 2011-06-22 2011-05  T T F F 
David 2011-06-01 2011-07-19 2011-06  T T F F 

回答

1

作爲回答第一個問題,你可以做

library(data.table) 
library(lubridate) 
dt <- data.table(df, key=c("dj", "exp")) 
dates <- setDT(transform(data.frame(start = seq.Date(as.Date("2011-05-01"), as.Date("2011-08-01"), "1 month")), 
            end = start + months(1) - 1), 
       key = c("start", "end")) 
dcast(foverlaps(dt, dates)[, val:=TRUE], names+dj+exp+cohort~start, value.var="val", fill=FALSE) 
# names   dj  exp cohort 2011-05-01 2011-06-01 2011-07-01 2011-08-01 
# 1: David 2011-06-01 2011-07-19 2011-06  FALSE  TRUE  TRUE  FALSE 
# 2: Jack 2011-05-03 2012-01-03 2011-05  TRUE  TRUE  TRUE  TRUE 
# 3: Tom 2011-05-01 2011-06-22 2011-05  TRUE  TRUE  FALSE  FALSE 

關於第二個問題,如果我理解正確的話,我會跟去

lst <- apply(df[2:3], 1, function(x) { x <- as.Date(x); as.logical(seq_along(seq(x[1], x[2], by="month"))) }) 
n <- max(lengths(lst)) 
res <- cbind(df, do.call(rbind, lapply(lst, function(x) `length<-`(x, n)))) 
res[is.na(res)] <- FALSE; res 
# names   dj  exp cohort 1 2  3  4  5  6  7  8  9 
# 1 Tom 2011-05-01 2011-06-22 2011-05 TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE 
# 2 David 2011-06-01 2011-07-19 2011-06 TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE 
# 3 Jack 2011-05-03 2012-01-03 2011-05 TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE 
+0

嗨盧克謝謝。第二個查詢是關於彙總加入月數的每個人。說M0是加入的月份,M1是加入的1個月,m2是加入的第二個月。 –

+0

第二個代碼中的插孔盧克數據不正確 –

+0

此外,如果不是非常適合隊列分析,因爲它沒有涵蓋每個月的月份範圍......無論如何,你是否在尋找「res」 ?如果你想要55個月,你可能想要改變'n <-55 ... – lukeA