R语言按另一列条件保留指定行及后续数据的技术问询
解决方案:按分组保留首次出现指定值后的所有行
嘿,我明白你要做的事了——按Cust_ID分组,只保留每个组里第一次出现Value = "A"的行以及之后的所有记录对吧?之前你找到的是取到最后一个"A"的逻辑,刚好反过来,我给你调整成你需要的版本,用dplyr和data.table都能轻松实现:
先确认你的示例数据
首先把你的示例数据转换成可运行的代码:
# 构造示例数据框 df1 <- data.frame( Cust_ID = c(500219,500219,500219,500219,500219,500219, 500220,500220,500220,500220,500220), Date = as.POSIXct(c("2016-04-11 12:00:00","2016-04-12 16:00:00", "2016-04-14 11:00:00","2016-04-15 12:00:00", "2016-05-23 09:00:00","2016-05-02 19:00:00", "2016-04-11 12:00:00","2016-04-14 11:00:00", "2016-04-15 12:00:00","2016-05-23 09:00:00", "2016-05-02 19:00:00")), Value = c("0","A","A","B","B","C","C","C","A","A","A") )
方法1:使用dplyr
这里用cumany()函数非常合适,它会在第一次满足条件后一直返回TRUE,完美匹配你的需求:
library(dplyr) result_dplyr <- df1 %>% group_by(Cust_ID) %>% filter(cumany(Value == "A")) %>% # 首次出现"A"后一直保留 ungroup() print(result_dplyr)
解释一下:cumany(Value == "A")会遍历每个分组的行,第一次遇到Value="A"时变成TRUE,之后所有行都保持TRUE,filter就会保留这些行。如果某个分组里没有"A",这个分组会被全部过滤掉——如果你想保留没有"A"的分组的所有行,可以改成filter(any(Value == "A") ? cumany(Value == "A") : TRUE)。
方法2:使用data.table
同样用cumany()的思路,写法更简洁:
library(data.table) setDT(df1) # 转换成data.table格式 result_dt <- df1[, .SD[cumany(Value == "A")], by = Cust_ID] print(result_dt)
.SD代表每个分组的子数据框,cumany(Value == "A")生成的逻辑向量用来筛选子数据框的行,效果和dplyr版本完全一致。如果要保留无"A"的分组,同样可以调整:df1[, .SD[if(any(Value == "A")) cumany(Value == "A") else TRUE], by = Cust_ID]。
验证结果
运行上面的代码后,得到的结果就是你期望的输出:每个客户从第一次出现"A"的行开始,所有后续行都被保留。
内容的提问来源于stack exchange,提问作者Fefton
相关产品推荐
相关产品推荐

