2015-05-25 46 views
3

我的數據框看起來像這樣。最右邊的兩列是我期望的列。從過去21天的窗口中提取事件類型

**Name  ActivityType  ActivityDate Email(last 21 says) Webinar(last21)**    
John  Email   1/1/2014  NA     NA 
John  Webinar   1/5/2014  NA     NA 
John  Sale    1/20/2014  Yes     Yes 
John  Webinar   3/25/2014  NA     NA 
John  Sale    4/1/2014  No     Yes 
John  Sale    7/1/2014  No     No 
Tom  Email   1/1/2015  NA     NA 
Tom  Webinar   1/5/2015  NA     NA 
Tom  Sale    1/20/2015  Yes     Yes 
Tom  Webinar   3/25/2015  NA     NA 
Tom  Sale    4/1/2015  No     Yes 
Tom  Sale    7/1/2015  No     No     

我只是想創建一個是/否變量,表示是否有電子郵件或在過去的21天,每個「銷售」交易網絡研討會。我正沿着使用dplyr這樣的思路思考(模擬代碼):

custlife %>% 
group_by(Name) %>% 
mutate(Email(last21days)=lag(ifelse(ActivityType = "Email" & ActivityDate of email within (activity date of sale - 21),Yes,No)). 

我不知道的方式來實現這一點。請幫助。您的幫助真誠地感謝!

+0

如果你有所有的日子,例如2014年1月1日,2014年2月1日,2014年3月1日......那麼你可以在'工作cumsum(Email)'和'lag(x,k = 21)'。順便說一下,在上述問題的背景下,NA電子郵件行可以被跳過。其他效率低下的方法是在不超過21天或同一天的時間內生成一組具有上述電子郵件的日期。然後做一個原始設置的連接。 – Pafnucy

+0

爲什麼'網絡研討會'行也有''是'「,你不是在檢查'銷售'行嗎? –

+0

@DavidArenburg你是對的。我在製作示例時犯了一個錯誤。謝謝你指出。 – gibbz00

回答

5

以下是可能的data.table解決方案。在這裏,我創建了2個臨時數據集 - 一個用於Sale,另一個用於其餘活動類型,然後通過21的滾動窗口連接它們,同時使用by = .EACHI來檢查每個連接中的條件。然後,我將結果加入原始數據集。

轉換日期列Date類和關鍵的姓名和日期的數據(最終/滾動加入)

library(data.table) 
setkey(setDT(df)[, ActivityDate := as.IDate(ActivityDate, "%m/%d/%Y")], Name, ActivityDate) 

每每項活動創建2個臨時數據集

Saletemp <- df[ActivityType == "Sale", .(Name, ActivityDate)] 
Elsetemp <- df[ActivityType != "Sale", .(Name, ActivityDate, ActivityType)] 

加入通過21的滾動窗口查詢銷售臨時數據集

Saletemp[Elsetemp, `:=`(Email21 = as.logical(which(i.ActivityType == "Email")), 
         Webinar21 = as.logical(which(i.ActivityType == "Webinar"))), 
     roll = -21, by = .EACHI] 

加入一切恢復

df[Saletemp, `:=`(Email21 = i.Email21, Webinar21 = i.Webinar21)] 
df 
#  Name ActivityType ActivityDate Email21 Webinar21 
# 1: John  Email 2014-01-01  NA  NA 
# 2: John  Webinar 2014-01-05  NA  NA 
# 3: John   Sale 2014-01-20 TRUE  TRUE 
# 4: John  Webinar 2014-03-25  NA  NA 
# 5: John   Sale 2014-04-01  NA  TRUE 
# 6: John   Sale 2014-07-01  NA  NA 
# 7: Tom  Email 2015-01-01  NA  NA 
# 8: Tom  Webinar 2015-01-05  NA  NA 
# 9: Tom   Sale 2015-01-20 TRUE  TRUE 
# 10: Tom  Webinar 2015-03-25  NA  NA 
# 11: Tom   Sale 2015-04-01  NA  TRUE 
# 12: Tom   Sale 2015-07-01  NA  NA 
+1

非常感謝David!我衷心感謝您的幫助。 – gibbz00

2

這裏是base R另一種選擇:

df是根據Name然後,每個分組中,每個Sale,它看起來如果有一個電子郵件(網絡研討會第一次分裂)從銷售21天內。最後,該列表根據Name未分離。
之後,您只需將FALSE替換成noTRUE再除以yes

df_split <- split(df, df$Name) 

df_split <- lapply(df_split, function(tab){ 
           i_s <- which(tab[,2]=="Sale") 
           tab$Email21[i_s] <- sapply(tab[i_s, 3], function(d_s){any(tab[tab$ActivityType=="Email", 3] >= d_s-21)}) 
           tab$Webinar21[i_s] <- sapply(tab[i_s, 3], function(d_s){any(tab[tab$ActivityType=="Webinar", 3] >= d_s-21)}) 
           tab 
           }) 
df_res <- unsplit(df_split, df$Name) 

df_res 
# Name ActivityType ActivityDate Email21 Webinar21 
#1 John  Email 2014-01-01  NA  NA 
#2 John  Webinar 2014-01-05  NA  NA 
#3 John   Sale 2014-01-20 TRUE  TRUE 
#4 John  Webinar 2014-03-25  NA  NA 
#5 John   Sale 2014-04-01 FALSE  TRUE 
#6 John   Sale 2014-07-01 FALSE  FALSE 
#7 Tom  Email 2015-01-01  NA  NA 
#8 Tom  Webinar 2015-01-05  NA  NA 
#9 Tom   Sale 2015-01-20 TRUE  TRUE 
#10 Tom  Webinar 2015-03-25  NA  NA 
#11 Tom   Sale 2015-04-01 FALSE  TRUE 
#12 Tom   Sale 2015-07-01 FALSE  FALSE 

數據

df <- structure(list(Name = c("John", "John", "John", "John", "John", 
"John", "Tom", "Tom", "Tom", "Tom", "Tom", "Tom"), ActivityType = c("Email", 
"Webinar", "Sale", "Webinar", "Sale", "Sale", "Email", "Webinar", 
"Sale", "Webinar", "Sale", "Sale"), ActivityDate = structure(c(16071, 
16075, 16090, 16154, 16161, 16252, 16436, 16440, 16455, 16519, 
16526, 16617), class = "Date")), .Names = c("Name", "ActivityType", 
"ActivityDate"), row.names = c(NA, -12L), index = structure(integer(0), ActivityType = c(1L, 
7L, 3L, 5L, 6L, 9L, 11L, 12L, 2L, 4L, 8L, 10L)), class = "data.frame")