嵌套tibble中使用lag()和mutate()关联前后数据生成新列表列
问题原因
你原来的嵌套写法不符合预期有两个核心原因:
nest_by()会生成行分组(rowwise)结构,此时mutate内调用lag(data)只能读取当前行上下文,无法正确获取上一行的嵌套data对象anti_join()返回的是tibble结构,直接赋值给新列时dplyr会自动按行展开,不会存储为你期望的列表列,需要手动用list()封装结果
正确的嵌套DataFrame实现
用普通的.by分组嵌套而非行分组,先创建滞后的data列,指定default参数,再封装join结果为列表列即可:
library(tidyverse) examp %>% # 按年份嵌套,不生成行分组 nest(.by = year, .key = "data") %>% # 生成滞后的上一周期data列,指定default为第一期的data mutate(prev_data = lag(data, default = data[[1]])) %>% # 封装anti_join结果为列表列 mutate(new_id_data = list(anti_join(data, prev_data, by = "id"))) %>% # 清理不需要的中间列 select(-prev_data)
运行后new_id_data就是标准的tibble列表列,直接调用unnest(new_id_data)即可展开所有新增id的行。
更简便的替代方案
你这个需求本质是筛选每个id首次出现的周期对应行,完全不需要嵌套或列表操作,用窗口函数即可实现,性能更优写法更简洁:
examp %>% group_by(id) %>% # 标记id首次出现的年份 filter(year == min(year)) %>% ungroup() %>% # 按你的需求,第一年和自身对比无新增,过滤掉第一年的结果 filter(year != min(year))
该输出结果和你最初用split + map2得到的结果完全一致。
内容的提问来源于stack exchange,提问作者fisher-j
相关产品推荐
相关产品推荐

