R dplyr按时间戳分组计算90%分位数新增列报错解决方法
问题描述
- 现有数据集包含大量记录,仅对应
:00、:01、:02三类不同时间戳 - 核心需求:按时间戳字段分组计算值字段的90%分位数,首先将分位数结果作为新列添加到原数据集,最终输出每个分位数对应一行的聚合结果
- 字段映射关系:数据中实际存储时间戳的字段为
Zeit,存储待计算数值的字段为R11_A1Shape1IP,时间戳字段已提前通过如下代码完成字符型转时间格式处理:
Daten[,"Zeit"]<- as.POSIXct(Daten[,"Zeit"],"%d.%m.%Y %H:%M:%S", tz=Sys.timezone())
已尝试方案与报错
可正常运行的参考代码
此前按时间戳分组取组内值最大值的代码运行正常:
Data <- Data %>% group_by(timestamp) %>% slice(which.max(val)) %>% ungroup(timestamp)
失败尝试1:误用slice计算分位数
直接将slice内取最大值的逻辑替换为分位数计算,触发类型报错:
Data <- Data %>% group_by(timestamp) %>% slice(quant90 = quantile(Val, probs = 0.9)) %>% ungroup(timestamp)
报错信息如下:
Error in `slice()`: ! Problem while computing indices. ℹ The error occurred in group 1: Zeit = 2022-06-02 04:08:05. Caused by error: ! Can't convert from <double> to <integer> due to loss of precision. • Locations: 1 Run `rlang::last_error()` to see where the error occurred.
失败尝试2:mutate生成分位列分组失效
更换为mutate生成新列后代码可运行,但分组逻辑未生效,所有行的90%分位数值完全一致:
Data <- Data %>% group_by(timestamp) %>% mutate(quant90 = quantile(Val, probs = 0.9))
期间已尝试手动执行as.double类型转换、调用tapply/apply等函数、加载多个dplyr相关工具库,均未成功实现需求。
解决方案
错误根因
slice()函数的作用是按整数类型的行位置索引筛选行,仅接受整数入参。传入分位数计算得到的浮点型数值时,会触发浮点数转整数的精度丢失报错,属于函数使用场景匹配错误。mutate生成分位数全表一致的核心原因是字段名不匹配:代码中分组引用的字段名是timestamp和Val,但实际数据中对应字段名为Zeit和R11_A1Shape1IP。分组时引用不存在的字段,dplyr会默认对全表数据计算分位数,最终所有行返回相同结果。
分步实现代码
步骤1:给原数据集新增分组90分位列
使用实际存在的字段名分组,通过mutate生成同组所有行取值一致的分位列,添加na.rm = TRUE避免缺失值导致计算结果异常:
library(dplyr) Data <- Data %>% group_by(Zeit) %>% mutate(quant90 = quantile(R11_A1Shape1IP, probs = 0.9, na.rm = TRUE)) %>% ungroup()
步骤2:生成分组聚合的单行结果
如果需要每个时间戳分组仅保留一行分位数结果,将mutate替换为summarise即可:
Data_agg <- Data %>% group_by(Zeit) %>% summarise(quant90 = quantile(R11_A1Shape1IP, probs = 0.9, na.rm = TRUE), .groups = "drop")
内容的提问来源于stack exchange,提问作者fox
相关产品推荐
相关产品推荐

