如何在dplyr中处理min_rank变体?实现连续分组的days求和
解决连续组合的days求和问题
你这里的问题在于min_rank(strength)是给strength做排名,不管这些相同strength的行是不是连续出现的——而你要的是连续出现的相同name+strength组合才合并求和,所以得换个思路:先给连续的相同组合打上专属分组标识,再按这个标识分组求和。
具体步骤和代码
首先确保你的数据是按时间顺序(date列)排列的,因为连续性是基于时间先后的,然后用cumsum()结合lag()来生成连续组的标识:
library(dplyr) # 假设你的原始数据是df,先按id和date排序保证顺序正确 result_df <- df %>% arrange(id, date) %>% group_by(id) %>% # 生成连续组标识:当name或strength和前一行不同时,组号+1 mutate( continuous_group = cumsum( row_number() == 1 | # 第一行直接归为第1组 name != lag(name) | strength != lag(strength) ) ) %>% # 按id和连续组分组,求和days group_by(id, continuous_group) %>% summarise( name = first(name), # 同一组内name是相同的,取第一个即可 strength = first(strength), # 同理,strength也相同 sumOfDays = sum(days), .groups = "drop" # 取消分组,避免后续操作受影响 ) %>% # 去掉不需要的continuous_group列,得到预期格式 select(id, name, strength, sumOfDays)
代码解释
arrange(id, date):必须先按id和date排序,否则如果数据乱序,连续的组合会被错误拆分,结果肯定不对。continuous_group生成:用cumsum()累计计数,当遇到第一行,或者当前行的name/strength和上一行(lag()获取前一行值)不同时,计数加1,这样连续的相同name+strength会被分到同一个组里。- 分组求和:按id和
continuous_group分组,取组内的name和strength(同一组内这些值完全相同),然后对days求和,最后去掉辅助的continuous_group列,就得到你想要的结果了。
验证你的示例数据
用你给出的示例数据测试,运行后会得到:
id name strength sumOfDays 1 a 10 60 1 a 5 30 1 a 10 20
完全符合你的预期输出。
内容的提问来源于stack exchange,提问作者hbabbar
相关产品推荐
相关产品推荐

