R语言dplyr分组调用tail()取组内最新记录结果异常问题
相同代码表现差异的原因
tail(., n=1)的执行逻辑是提取分组内按数据原始存储顺序排列的最后1行,本身不会自动按日期排序筛选最新记录:
- 处理
df2时结果正确完全是巧合:df2里每个ticker分组的行刚好是按日期从小到大依次存储的,最后一行正好对应分组内最新日期的记录。 - 处理
df时结果错误是必然:df每个Position分组内的行没有按日期升序排列,你查到的2022-07-01的记录并不在对应分组的最后一个存储位置,tail自然取到了更早日期的错误记录。比如Position=1分组的最后一行存储的是2021-12-30的记录,而2022-07-01的记录存在于分组中间位置,就被漏掉了。
正确调整方案
不要依赖数据集原始的行顺序,显式按日期字段筛选每个分组的最大值即可,两种常用可靠写法如下:
写法1:推荐用slice_max(dplyr 1.0.0及以上版本支持)
代码最简洁,语义最清晰,不需要提前排序:
# 处理df df %>% group_by(Position) %>% slice_max(order_by = Date, n = 1, with_ties = FALSE) # 处理df2也建议换成这个写法,避免后续数据顺序变化导致结果出错 df2 %>% group_by(ticker) %>% slice_max(order_by = date, n = 1, with_ties = FALSE)
参数说明:
with_ties = FALSE表示如果分组内有多条记录同为最新日期,只返回1条;如果需要保留所有最新日期的记录,去掉这个参数即可。
写法2:兼容旧版本dplyr的写法
先在分组内按日期升序排序,再取最后一行:
df %>% group_by(Position) %>% arrange(Date, .by_group = TRUE) %>% slice_tail(n = 1)
内容的提问来源于stack exchange,提问作者Juan M
相关产品推荐
相关产品推荐

