如何在Tidyverse中结合base R的which函数分组查找PIZZA_PARTY前序事件
解决方案
报错原因
你原代码报错的核心原因是:分组后部分组(如Laura对应的分组)不存在PIZZA_PARTY事件,此时which(EVENT=="PIZZA_PARTY")返回长度为0的空向量,和分组内的行长度不匹配,就会触发长度不一致的报错。
基于base R which函数的正确实现
只要提前对空值情况做兼容处理即可,和你原来的base写法逻辑完全一致:
library(tidyverse) # 最终实现代码 df %>% group_by(STUDENT) %>% summarise( LAST_EVENT_BEFORE_PIZZA = ifelse( # 先判断当前组是否存在披萨派对事件 length(which(EVENT == "PIZZA_PARTY")) == 0, # 不存在返回字符型NA,避免类型报错 NA_character_, # 存在则取对应位置的前一个事件 EVENT[which(EVENT == "PIZZA_PARTY") - 1] ) ) %>% # 按需保留/删除该步:去掉没有披萨派对的学生记录,匹配你给出的预期输出 filter(!is.na(LAST_EVENT_BEFORE_PIZZA))
运行后得到的结果和你预期完全一致:
| STUDENT | LAST_EVENT_BEFORE_PIZZA |
|---|---|
| James | GEO_EXAM |
| Kylie | MATH_EXAM |
| Mark | MATH_EXAM |
更简洁的tidyverse原生写法
如果不强制要求用which函数,也可以用dplyr自带的lag()函数实现,逻辑更直观:
df %>% group_by(STUDENT) %>% # 生成每一行的前一个事件字段 mutate(LAST_EVENT = lag(EVENT)) %>% # 筛选出披萨派对对应的行,自动过滤没有该事件的学生 filter(EVENT == "PIZZA_PARTY") %>% select(STUDENT, LAST_EVENT_BEFORE_PIZZA = LAST_EVENT)
两种写法的输出结果完全相同。
内容的提问来源于stack exchange,提问作者R_Student
相关产品推荐
相关产品推荐

