按id分组定位每组中source=A的最后消息行号(R语言)
解决方案:定位每个分组中source=A的最后一条消息
我明白你的需求啦——要在每个id(会话)分组里,找到source为A的最后一条消息,并把对应行的value设为1,其余行设为0。你之前的代码只取了每个分组的最后一行,没有针对source=A的条件筛选,所以才达不到目标。
这里给你一个用dplyr实现的正确方案,完全贴合你的需求:
library(dplyr) # 假设你的原始数据框名为dat dat <- dat %>% group_by(id) %>% # 第一步:在每个id分组里,计算source=A的消息的最大msgid(也就是最后一条A的序号) mutate(max_A_msgid = max(msgid[source == "A"], na.rm = TRUE)) %>% # 第二步:判断当前行是否是该分组里最后一条A的消息,是则设为1,否则0 mutate(value = ifelse(msgid == max_A_msgid & source == "A", 1, 0)) %>% # 移除临时计算的辅助列 select(-max_A_msgid) %>% ungroup()
代码解释:
max(msgid[source == "A"], na.rm = TRUE):在每个id分组内,先筛选出所有source=A的行,再取这些行里最大的msgid(也就是会话中最后一条A的消息序号)。na.rm=TRUE是为了处理某个分组里没有A消息的情况,此时max会返回NA,后续判断会自动把所有行设为0。ifelse(msgid == max_A_msgid & source == "A", 1, 0):同时校验msgid匹配且source=A,避免极端情况(比如某个分组最后一行是B,但msgid刚好等于其他分组的max_A_msgid)。
测试你的示例数据:
运行代码后,你的示例数据会变成:
| id | msgid | source | value |
|---|---|---|---|
| 1 | 1 | B | 0 |
| 1 | 2 | A | 1 |
| 1 | 3 | B | 0 |
| 2 | 1 | B | 0 |
| 2 | 2 | A | 0 |
| 2 | 3 | A | 1 |
| 2 | 4 | B | 0 |
完美符合你想要的结果!
内容的提问来源于stack exchange,提问作者Shoaibkhanz
相关产品推荐
相关产品推荐

