R语言:提取分组数据集指定分位数及边界情况处理
解决方案
针对你的问题,核心是当没有Cum ≤ 阈值的数据时,回退选取Cum最小的行对应的Size。你原代码的问题在于filter(Cum <= 10)后得到空数据集时,which.min(Size)会返回NA,导致最终结果缺失。下面提供两种可行的实现方式:
方式1:处理原列表格式的数据集
如果你的数据保持列表结构(每个元素对应一个站点的数据),可以用purrr::map结合条件判断实现需求:
library(dplyr) library(purrr) # 定义目标阈值 target_threshold <- 10 # 处理每个站点的数据 result <- map(df, function(station_data) { # 筛选符合Cum ≤ 阈值的行 valid_rows <- station_data %>% filter(Cum <= target_threshold) if (nrow(valid_rows) > 0) { # 存在符合条件的行,选取Size最小的那一行 valid_rows %>% slice_min(Size, n = 1) } else { # 无符合条件的行,选取Cum最小的那一行 station_data %>% slice_min(Cum, n = 1) } }) # 查看结果 result
逻辑说明
- 对每个站点数据,先筛选
Cum ≤ 阈值的行; - 如果筛选结果非空,用
slice_min(Size)提取其中最小的Size(即使Size未排序,该方法也能生效); - 如果筛选结果为空,直接提取
Cum最小的行(即该站点累积占比最小的记录)。
方式2:合并数据集后按站点分组处理
如果将所有站点数据合并为单个数据框,用group_by可以更高效地批量处理多个阈值(比如同时提取10%和50%分位数):
library(dplyr) # 将列表合并为单个数据框 df_combined <- bind_rows(df) # 定义需要提取的多个阈值 thresholds <- c(10, 50) # 按站点分组,提取每个阈值对应的Size result_multi <- df_combined %>% group_by(SubStation) %>% summarise( across(all_of(thresholds), ~{ # 判断是否存在Cum ≤ 当前阈值的行 has_valid <- any(Cum <= .x) if (has_valid) { min(Size[Cum <= .x]) } else { Size[which.min(Cum)] } }), .groups = "drop" ) # 查看结果 result_multi
输出示例
针对你提供的示例数据集,上述代码会返回:
| SubStation | 10 | 50 |
|---|---|---|
| B | 40 | 34 |
| M1 | 42 | 31 |
| M2 | 36 | 34 |
| M3 | 34 | 33 |
内容的提问来源于stack exchange,提问作者RadRel
相关产品推荐
相关产品推荐

