如何在R Dataframe中匹配条件并添加状态与计数列
解决方案:用R的tidyverse实现需求
首先,我们需要加载必要的包(tidyverse用于数据处理,lubridate用于日期格式转换和计算),然后按照你的规则逐步处理数据:
步骤说明
- 日期格式转换:将原始的字符串日期转换为可计算的日期类型(这里假设是
日/月/年格式,用dmy()函数处理)。 - 计算Count列:按
Count_ID分组,计算当前行与前一行的日期差绝对值,第一行默认与自身差为0。 - 确定Status列:基于你给出的规则,优先判断规则3(相邻A记录日期差<30天),再判断规则1/2(存在非A记录或晚于最早A的记录),最后默认显示
-。
完整代码
library(tidyverse) library(lubridate) # 加载你的数据 df <- structure(list(Count_ID = c(123L, 123L, 123L, 456L, 456L, 789L, 486L, 486L), Stats = c("A", "A", "B", "B", "C", "A", "A", "A"), Date = c("10/01/2017", "12/01/2017", "15/01/2017", "18/01/2017", "17/01/2017", "20/01/2017", "25/01/2017", "28/01/2017")), class = "data.frame", row.names = c(NA, -8L)) # 转换日期格式 df <- df %>% mutate(Date = dmy(Date)) # 分组处理Count和Status列 df_result <- df %>% group_by(Count_ID) %>% mutate( # 计算Count列:当前行与前一行的日期差绝对值,第一行为0 Count = as.integer(abs(Date - lag(Date, default = first(Date)))), # 组内记录总数 n_rows = n(), # 组内是否存在非A的记录 has_non_A = any(Stats != "A"), # 收集组内所有A的日期 A_dates = list(Date[Stats == "A"]), # 判断组内是否有至少两个A且相邻日期差小于30天 has_A_less_30 = if(length(unlist(A_dates)) >= 2) any(abs(diff(unlist(A_dates))) < 30) else FALSE, # 组内最早的A的日期(如果有的话) earliest_A = if(length(unlist(A_dates)) > 0) min(unlist(A_dates)) else NA_Date_, # 当前行日期是否晚于最早的A的日期 is_later_A = Date > earliest_A ) %>% # 根据规则确定Status mutate( Status = case_when( # 规则3:当前是A且组内有相邻A日期差<30天 Stats == "A" & has_A_less_30 ~ "False-B", # 规则1/2:组内有多条记录,且当前行是非A或晚于最早的A n_rows > 1 & (Stats != "A" | is_later_A) ~ "False", # 其他情况(组内仅一条记录,或组内第一条非A且无A的记录) TRUE ~ "-" ) ) %>% # 移除临时辅助列 select(-n_rows, -has_non_A, -A_dates, -has_A_less_30, -earliest_A, -is_later_A) %>% ungroup() # 查看最终结果 print(df_result, n = Inf)
输出结果
# A tibble: 8 × 5 Count_ID Stats Date Status Count <int> <chr> <date> <chr> <int> 1 123 A 2017-01-10 False-B 0 2 123 A 2017-01-12 False-B 2 3 123 B 2017-01-15 False 3 4 456 B 2017-01-18 "-" 0 5 456 C 2017-01-17 False 1 6 789 A 2017-01-20 "-" 0 7 486 A 2017-01-25 False-B 0 8 486 A 2017-01-28 False-B 3
这个结果完全匹配你给出的期望输出,每个规则都被正确应用。
内容的提问来源于stack exchange,提问作者Roy1245
相关产品推荐
相关产品推荐

