【问题标题】:Aggregating by Customer with logic around dates windowing function使用围绕日期窗口函数的逻辑按客户聚合
【发布时间】:2016-12-04 14:49:29
【问题描述】:

有人可以帮我解决以下问题吗?我在附件中有这个 data.frame 需要处理

从交易代码 1 开始 - 必须跟踪客户的所有交易,并且必须在 30 天的时间范围内汇总金额。并且计数器再次为客户重新启动,以便为具有 Transaction code 1 的另一笔交易创建新的汇总记录。并且事务代码为 0 或 1 的事务独立仍将是输出数据帧的一部分,但作为未聚合的行。

我已经尝试过 dplyr、group_by 函数和总结,但我卡住的部分是在函数中包含条件以获得正确答案。

如果我在控制台中输入dput(df),我会得到以下信息:

> dput(df) structure(list(Customer_ID = c(1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3), date = structure(c(1L, 2L, 3L, 4L, 7L, 10L, 11L, 5L, 6L, 8L, 9L, 12L), .Label = c("01/01/2016", "02/01/2016", "02/15/2016", "02/30/2016", "04/01/2016", "04/20/2016", "05/01/2016", "05/05/2016", "06/01/2016", "07/01/2016", "07/15/2016", "10/01/2016"), class = "factor"), Amount = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), Transaction_Code = c(0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1)), .Names = c("Customer_ID", "date", "Amount", "Transaction_Code"), row.names = c(NA, -12L ), class = "data.frame") 

【问题讨论】:

  • 如果您的数据位于 r 中名为 df 的变量中,您可以在控制台中输入 dput(df),然后将该输出复制并粘贴到您的问题中。

标签: r


【解决方案1】:

对不起,我一开始没看懂你的问题,应该注意了windowing function的参考。这是我的尝试,它并不漂亮,可能有一种更优雅的方式使用 dplyr 或 data.table 包,但它得到了你发布的答案。

#your data frame 
x <- structure(list(Customer_ID = c(1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3), date = structure(c(1L, 2L, 3L, 4L, 7L, 10L, 11L, 5L, 6L, 8L, 9L, 12L), .Label =  c("01/01/2016", "02/01/2016", "02/15/2016", "02/28/2016", "04/01/2016", "04/20/2016", "05/01/2016", "05/05/2016", "06/01/2016", "07/01/2016", "07/15/2016", "10/01/2016"), class = "factor"), Amount = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), Transaction_Code = c(0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1)), .Names = c("Customer_ID", "date", "Amount", "Transaction_Code"), row.names = c(NA, -12L ), class = "data.frame")

#changed date '2/30/2016' to '2/28/2016' to recognize as a real date

x$date <- as.Date(x$date, format = "%m/%d/%Y")

library(dplyr)

x <- x %>% group_by(Customer_ID) %>%
     #calculate difference between current row date and prev row date (in days)
  mutate(date2 = as.numeric(difftime(date, lag(date,1)))) %>%
     #convert NAs to 0 for start of each customer (needed for cumsum function)
  mutate(date2 = ifelse(is.na(date2), 0, date2)) %>%
     #convert cumsum of days into ranges of 30 & truncate to remove decimals
  mutate(date3 = trunc((cumsum(date2))/30)) %>%
     #re-group by customer and date range period
  group_by(Customer_ID,date3) %>%
     #calculate total Amount per range period
  summarise(totAmt = sum(Amount))

print(x)

Source: local data frame [8 x 3]
Groups: Customer_ID [?]

    Customer_ID date3 totAmt
    <dbl> <dbl>  <dbl>
1           1     0      1
2           1     1      3
3           1     4      1
4           1     6      2
5           2     0      2
6           2     1      1
7           3     0      1
8           3     4      1

【讨论】:

  • 感谢科利尔的回复。我能够通过在 lubridate 中使用月份函数来创建一个新的列。在那之后,虽然我可以汇总每个客户每月的金额,但这并不能完全解决我的问题。我希望能够为客户总结从第一个交易代码 =1 开始的一个月。
  • 非常感谢科利尔!你先生!是个天才!感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-28
相关资源
最近更新 更多