【问题标题】:Events in last 21 days for every row by Name过去 21 天按名称显示的每一行的事件
【发布时间】:2015-06-10 15:25:44
【问题描述】:

这就是我的数据框的样子。最右边的两列是我想要的列。这两列检查过去 21 天内是否有“Email”ActivityType 以及过去 21 天内是否有“Webinar”ActivityType 的条件。

 Name      ActivityType     ActivityDate  Email(last21days) Webinar(last21day)**             
John       Email            1/1/2014        TRUE                  NA   
John       Webinar          1/5/2014        TRUE                 TRUE
John       Sale             1/20/2014       TRUE                 TRUE
John       Webinar          3/25/2014       NA                   TRUE
John       Sale             4/1/2014        NA                   TRUE
John       Sale             7/1/2014        NA                   NA
Tom        Email            1/1/2015        TRUE                   NA   
Tom        Webinar          1/5/2015        TRUE                 TRUE
Tom        Sale             1/20/2015      TRUE                 TRUE
Tom        Webinar          3/25/2015       NA                   TRUE
Tom        Sale              4/1/2015        NA                   TRUE
Tom        Sale              7/1/2015       NA                   NA

根据此处的帮助: Extracting event types from last 21 day window 我试过了:

df$ActivityDate <- as.Date(df$ActivityDate)
library(data.table)
setDT(df)
setkey(df, Name,ActivityDate)
Elsetemp <- df[, .(Name, ActivityDate, ActivityType)]
df[Elsetemp, `:=`(Email21 = as.logical(which(i.ActivityType == "Email")), 
                        Webinar21 = as.logical(which(i.ActivityType == "Webinar"))), 
         roll = -21, by = .EACHI]

无济于事,因为我只得到TRUEs 用于“销售”的行。例如,ActivityType = Webinar 的第二行,Email21 和 Webinar21 都应为 TRUE。当我定义过去 21 天时,我试图将事件发生的那一天也包括在内。

【问题讨论】:

  • 您应该描述您想要的列,而不仅仅是显示它们。除非大卫已经参与问答,例如通过在此处发表评论,否则大卫不会收到您的 ping。此外,日期是乱七八糟的东西,所以也许你可以把你的 data.frame 的结构不仅仅是它的图片。 CathG 在回答您的最后一个问题时为您做到了这一点。

标签: r dataframe data.table dplyr


【解决方案1】:

这个怎么样?

使用来自data.table滚动连接

require(data.table)
dt[, ActivityDate := as.Date(ActivityDate, format="%m/%d/%Y")]
setkey(dt, Name, ActivityDate)

roll_index <- function(x, types, roll=21) {
    lapply(types, function(type) {
         idx = x[ActivityType == type][x, roll=roll, which=TRUE]
         as.logical(idx)
    })
}
dt[, c("Email_21", "Webinar_21") := roll_index(dt, c("Email", "Webinar"))]

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

【讨论】:

  • 非常感谢。这完美地工作。如果您愿意在您的代码中添加一些 cmets,那就太棒了,因为我不知道您定义 roll_index 时发生了什么。
  • 我将把它留给你作为练习。查看?data.table 并完成示例。还要通过vignettes。这将有助于您完成未来的任务。
  • 谢谢。如果我想向前看 21 天而不是像本例中那样向前看 21 天(向后)怎么办?我使用 roll = -21 吗?
  • 要查找未来 21 天,roll=-21,是的(检查 ?data.table 中的 roll 参数)。我不知道你期望什么,你得到什么。无论如何,这是一个新问题。我再次建议你花时间学习一个包,如果你打算使用它,而不是为你的任务的每一个变化寻求解决方案。
  • 非常感谢。我已经报名参加了由您共同举办的 data.table 数据营课程。
【解决方案2】:

基础 R 解决方案:

#New type of sequence function that can accept vectors
seq2 <- function(v1) {
  res <- list()
  for(i in seq_along(v1)) {
    res[[i]] <- seq(v1[i], v1[i]+21, by='day')
  }
  as.Date(unlist(res), origin='1970-01-01')
}

df <- df[ ,1:3]
df$ActivityDate <- as.Date(df$ActivityDate, format='%m/%d/%Y')

#Email column
emailed <- df[df$ActivityType == 'Email', 'ActivityDate']
df$Email <- df$ActivityDate %in% seq2(emailed)

#Webinar column
webbed <- df[df$ActivityType == 'Webinar', 'ActivityDate']
df$Webinar <- df$ActivityDate %in% seq2(webbed)

首先,我们对前三列进行子集化,但不包含示例输出。然后用as.Date 转换日期因子。向量emailed 使用Email 字符串查找ActivityType。创建函数seq2 是为了查找日期和21 天之后。它创建了一个可以检查的序列。

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

数据

df <- read.table(text=' Name      ActivityType     ActivityDate  Email(last21days) Webinar(last21day)**             
John       Email            1/1/2014        TRUE                  NA   
John       Webinar          1/5/2014        TRUE                 TRUE
John       Sale             1/20/2014       TRUE                 TRUE
John       Webinar          3/25/2014       NA                   TRUE
John       Sale             4/1/2014        NA                   TRUE
John       Sale             7/1/2014        NA                   NA
Tom        Email            1/1/2015        TRUE                   NA   
Tom        Webinar          1/5/2015        TRUE                 TRUE
Tom        Sale             1/20/2015      TRUE                 TRUE
Tom        Webinar          3/25/2015       NA                   TRUE
Tom        Sale              4/1/2015        NA                   TRUE
Tom        Sale              7/1/2015       NA                   NA', header=T)

【讨论】:

  • 我需要调整组合逻辑。截至目前,它匹配所有小于或等于 21 天的日期。我需要将其设为 21 的范围。将继续解决。
  • 我想你想在活动日期上加 21 以找到相关的日期范围。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-05
  • 2020-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多