我有一个客户交易数据集,需要基于一组相当复杂的“时间”规则创建一个新列(Vintage):
简而言之,要求是按名称出现在书中的日期标记每个条目(行)(即它们何时是“新”“运动”)。在实际应用中,有几种情况需要考虑:
如果名称首次出现在带有“EXISTING”标签的数据集中,则 Vintage = 'Back Book'
如果相同名称在稍后的报告日期有“新”标签 - 年份将成为“新”条目的日期
对于“新”标签后面的“现有”条目 - 年份 = 最近的“新”条目日期
如果该名称有新的“NEW”条目,则 Vintage 值将成为新“NEW”条目的日期
这可能听起来很复杂,所以我添加了下图来说明所有可能情况下的预期结果:
重新创建玩具数据集的代码:
structure(list(Date = c(20240430L, 20240531L, 20240630L, 20240229L,
20240331L, 20240531L, 20240630L, 20240731L, 20230930L, 20231031L,
20231231L, 20230930L, 20231031L, 20231231L, 20240531L, 20240731L
), Name = structure(c(1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 3L, 3L,
3L, 4L, 4L, 4L, 4L, 4L), .Label = c("A", "B", "C", "D"), class = "factor"),
Movement = structure(c(1L, 1L, 1L, 1L, 1L, 2L, 1L, 1L, 2L,
1L, 1L, 1L, 1L, 2L, 1L, 2L), .Label = c("EXISTING", "NEW"
), class = "factor"), Vintage = structure(c(5L, 5L, 5L, 5L,
5L, 3L, 3L, 3L, 1L, 1L, 1L, 5L, 5L, 2L, 2L, 4L), .Label = c("20230930",
"20231231", "20240531", "20240731", "Back Book"), class = "factor")), class = "data.frame", row.names = c(NA,
-16L))
我正在寻找一个可以有效地创建“Vintage”列的代码,因为数据集有超过 100k 条目并且不断增长。谢谢!
我尝试创建数据集的两个副本(df_A,df_B),并使用 rowwise()、mutate() 和从 mutate() 内调用的自定义“assignVintage”函数从 df_A 到 df_B 查找每一行的 Vintage ,但是代码只执行所需时间规则的子集,尽管效率仍然非常低,运行时间超过 20 分钟 - 这就是为什么我正在寻找一种更优雅的解决方案(如果存在)。
这是一个解决方案。
Movement
是 "NEW"
;"Back Book"
,如果是并且是组的第一个元素,则分配日期,否则分配 NA
;NA
。library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
df1 %>%
mutate(new = cumsum(Movement == "NEW"), .by = Name) %>%
mutate(
Vintage2 = case_when(
new == 0 ~ "Back Book",
new > 0 & Movement == "NEW" ~ as.character(Date),
TRUE ~ NA_character_
),
.by = new
) %>%
tidyr::fill(Vintage2) %>%
select(-new)
#> Date Name Movement Vintage Vintage2
#> 1 20240430 A EXISTING Back Book Back Book
#> 2 20240531 A EXISTING Back Book Back Book
#> 3 20240630 A EXISTING Back Book Back Book
#> 4 20240229 B EXISTING Back Book Back Book
#> 5 20240331 B EXISTING Back Book Back Book
#> 6 20240531 B NEW 20240531 20240531
#> 7 20240630 B EXISTING 20240531 20240531
#> 8 20240731 B EXISTING 20240531 20240531
#> 9 20230930 C NEW 20230930 20230930
#> 10 20231031 C EXISTING 20230930 20230930
#> 11 20231231 C EXISTING 20230930 20230930
#> 12 20230930 D EXISTING Back Book Back Book
#> 13 20231031 D EXISTING Back Book Back Book
#> 14 20231231 D NEW 20231231 20231231
#> 15 20240531 D EXISTING 20231231 20231231
#> 16 20240731 D NEW 20240731 20240731
创建于 2024-08-21,使用 reprex v2.1.0