使用lubridate实现行间日期比较及业务逻辑的报错问题
问题描述
我需要对各门店的购买日期做行间比较,实现三个逻辑:
- 计算连续两次购买的间隔天数
- 判断间隔是否≥60天
- 记录当前及上一次购买的商品
参考相关代码后,在日期比较环节报错,现提供示例数据、期望输出及错误代码,寻求正确实现方法。
示例数据
mydata <- data.frame( store = c('A', 'B', 'A', 'B', 'A', 'B', 'A', 'B'), PurchaseDate = c('2023-01-01', '2023-01-01', '2023-02-01', '2023-03-01', '2023-04-01', '2023-04-01', '2023-05-01', '2023-06-01'), sales = c("apples", "bananas", "cherries", "bananas", "cherries", "cherries", "bananas", "bananas") ) mydata$PurchaseDate <- as.Date(mydata$PurchaseDate)
期望输出
store PurchaseDate sales LastPurchase over60 LastSale A 2023-01-01 apples 0 0 NA A 2023-02-01 cherries 32 0 apples A 2023-04-02 cherries 61 1 cherries A 2023-05-01 bananas 31 0 cherries B 2023-01-01 bananas 0 0 NA B 2023-03-02 bananas 61 1 bananas B 2023-04-01 cherries 31 0 bananas B 2023-06-01 bananas 62 1 cherries
错误代码
mydata %>% group_by(store) |> arrange((PurchaseDate), .by_group = TRUE) |> mutate(over60 = ifelse(abs(difftime(PurchaseDate, lag(sales, default =first(PurchaseDate)), units = "days")) < 60, 0, 1))
错误原因分析
- 列引用错误:代码中用
lag(sales)取上一行的商品名称,而非上一次购买日期,导致日期比较时类型不匹配报错。 - 默认值类型不兼容:
lag()的default参数传入日期类型的first(PurchaseDate),但lag(sales)对应的是字符类型,两者无法匹配。 - 逻辑冗余:已按购买日期升序排序,无需用
abs(),直接用当前日期减上一次日期即可得到间隔天数。
正确实现代码
library(dplyr) result <- mydata %>% group_by(store) %>% arrange(PurchaseDate, .by_group = TRUE) %>% mutate( # 计算间隔天数,首次购买间隔设为0 LastPurchase = as.integer(difftime(PurchaseDate, lag(PurchaseDate, default = first(PurchaseDate)), units = "days")), # 判断间隔是否≥60天 over60 = ifelse(LastPurchase >= 60, 1, 0), # 获取上一次购买的商品,首次记录为NA LastSale = lag(sales) ) result
说明
- 按门店分组后先对购买日期升序排序,确保行间是连续的购买记录。
lag(PurchaseDate, default = first(PurchaseDate))让首次购买时用自身日期计算,间隔自动为0,符合期望输出要求。as.integer()将时间差结果转为整数天数,和期望输出格式一致。lag(sales)直接获取上一行的商品名称,首次记录自动为NA,无需额外处理。
内容的提问来源于stack exchange,提问作者plover
相关产品推荐
相关产品推荐

