我试图跟踪特定属性在列中的最后一个实例,但似乎无法为我工作。例如,如果我有一个交易数据库,我想保留购买的特定项目子集(在本例中为Drill)中最后一个的运行标志,以便:
Transactions <- data.table(Customer=c("A01","A01","A01","A01","A01","A01"),
PurchaseDate=c("1/1/2018","1/2/2018","1/3/2018","1/4/2018","1/5/2018","1/6/2018"),
Purchase=c("DrillA, Bit10", "Bit11","Bit20","Bit21","DrillZ, Bit4", "Bit6"))
成为:
Transactions <- data.table(Customer=c("A01","A01","A01","A01","A01","A01"),
PurchaseDate=c("1/1/2018","1/2/2018","1/3/2018","1/4/2018","1/5/2018","1/6/2018"),
Purchase=c("DrillA, Bit10", "Bit11","Bit20","Bit21","DrillZ, Bit4", "Bit6"),
LastDrill=c("DrillA","DrillA","DrillA", "DrillA", "DrillZ", "DrillZ"))
我原本以为我可以用case_when处理这个,但是我看不到过去的那一行:
Transactions %>%
arrange(Customer, PurchaseDate) %>%
group_by(Customer) %>%
mutate(LastDrill = "") %>%
mutate(LastDrill = case_when(grepl("DrillA", Purchase) ~ "DrillA",
grepl("DrillZ", Purchase) ~ "DrillZ",
TRUE ~ lag(LastDrill, 1, order_by=PurchaseDate)))
这似乎适用于紧随包含“ DrillA / DrillZ”的事务之后的事务,但是并不能保持“ flag”的进行。
是否有更好的方法来构造它?任何帮助将不胜感激!
答案 0 :(得分:1)
数据
Transactions <- data.frame(Customer=c("A01","A01","A01","A01","A01","A01"),
PurchaseDate=c("1/1/2018","1/2/2018","1/3/2018","1/4/2018","1/5/2018","1/6/2018"),
Purchase=c("DrillA, Bit10", "Bit11","Bit20","Bit21","DrillZ, Bit4", "Bit6"))
选项1 (tidyverse和重塑)
library(tidyverse)
Transactions %>%
arrange(Customer, PurchaseDate) %>%
group_by(Customer) %>%
separate_rows(Purchase) %>% # separate column into multiple rows (i.e. one event per row)
mutate(flag = cumsum(grepl("Drill", Purchase))) %>% # group rows based on when drills occur
group_by(flag, add = T) %>%
mutate(LastDrill = first(Purchase)) %>% # get the first value in a new column (should always be a drill)
ungroup() %>%
select(-flag) %>%
group_by(Customer, PurchaseDate, LastDrill) %>%
summarise(Purchase = paste0(Purchase, collapse = ", ")) %>% # go back to your original shape
ungroup()
# Customer PurchaseDate Purchase LastDrill
# 1 A01 1/1/2018 DrillA, Bit10 DrillA
# 2 A01 1/2/2018 Bit11 DrillA
# 3 A01 1/3/2018 Bit20 DrillA
# 4 A01 1/4/2018 Bit21 DrillA
# 5 A01 1/5/2018 DrillZ, Bit4 DrillZ
# 6 A01 1/6/2018 Bit6 DrillZ
选项2 (dplyr和提取练习的功能)
library(dplyr)
library(zoo)
# vectorised function to extract the drill value from a string
# (uses comma to split the string)
GetDrill = function(x) { y = unlist(strsplit(x, split = ","))
ifelse(sum(grepl("Drill", y)), y[grepl("Drill", y)], NA) }
GetDrill = Vectorize(GetDrill)
Transactions %>%
arrange(Customer, PurchaseDate) %>%
group_by(Customer) %>%
mutate(LastDrill = na.locf(GetDrill(as.character(Purchase)))) %>%
ungroup()
# # A tibble: 6 x 4
# Customer PurchaseDate Purchase LastDrill
# <fct> <fct> <fct> <chr>
# 1 A01 1/1/2018 DrillA, Bit10 DrillA
# 2 A01 1/2/2018 Bit11 DrillA
# 3 A01 1/3/2018 Bit20 DrillA
# 4 A01 1/4/2018 Bit21 DrillA
# 5 A01 1/5/2018 DrillZ, Bit4 DrillZ
# 6 A01 1/6/2018 Bit6 DrillZ