如何在R DataFrame中基于性能峰值年龄筛选非支配数据行?
需求实现方案
问题背景
我有一个包含age(年龄)和performance(性能)两列的R DataFrame,每条记录对应一个唯一年龄,需要完成以下数据清洗:
- 对于年龄大于性能最大值对应年龄的行,删除所有性能值低于任意更高年龄性能值的行;
- 对于年龄小于性能最大值对应年龄的行,删除所有性能值低于任意更低年龄性能值的行。
示例数据
df <- structure(list(age = c(31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74), performance = c(3.2341087962963, 3.13613425925926, 3.1553125, 3.22259259259259, 3.11091435185185, 3.41855324074074, 3.21152777777778, 3.12123842592593, 3.49372685185185, 3.69923611111111, 3.51280092592593, 3.30284722222222, 3.09113425925926, 3.01299768518518, 3.05696759259259, 3.3383912037037, 3.1884837962963, 3.00399305555556, 3.01096064814815, 3.0466087962963, 3.06674768518519, 3.05023148148148, 3.0993287037037, 2.84232638888889, 2.90362268518519, 2.82956018518519, 3.02834490740741, 2.74263888888889, 2.87833333333333, 2.56236111111111, 2.73252314814815, 2.48283564814815, 2.7869212962963, 2.50503472222222, 2.46137731481481, 2.4915162037037, 2.4375, 2.12164351851852, 2.413125, 2.38354166666667, 2.08234953703704, 1.77328703703704, 1.87770833333333, 2.00084490740741)), row.names = c(NA, -44L), class = "data.frame")
数据可视化

实现代码
# 1. 定位性能峰值对应的年龄 peak_age <- df$age[which.max(df$performance)] # 2. 拆分数据 left_part <- df[df$age < peak_age, ] peak_row <- df[df$age == peak_age, ] right_part <- df[df$age > peak_age, ] # 3. 处理左侧:保留性能不低于所有更年轻观测的行 left_part$cum_max <- cummax(left_part$performance) left_filtered <- left_part[left_part$performance == left_part$cum_max, c("age", "performance")] # 4. 处理右侧:保留性能不低于所有更年长观测的行 # 先逆序,计算累计最大值后筛选,再恢复原顺序 right_reversed <- right_part[order(right_part$age, decreasing = TRUE), ] right_reversed$cum_max <- cummax(right_reversed$performance) right_filtered <- right_reversed[right_reversed$performance == right_reversed$cum_max, c("age", "performance")] right_filtered <- right_filtered[order(right_filtered$age), ] # 5. 合并结果 final_df <- rbind(left_filtered, peak_row, right_filtered) # 查看筛选后的数据 print(final_df)
代码逻辑说明
- 先找到性能最高的年龄作为分界点,把数据分成左(年龄更小)、中(峰值)、右(年龄更大)三部分;
- 左侧按年龄从小到大计算累计最大值,只保留等于累计最大值的行——这样每一行的性能都不会比之前任何更年轻的观测低;
- 右侧需要从大到小计算累计最大值(因为要对比更高年龄的性能),筛选后再恢复正序,确保每一行性能不比任何更年长的观测低;
- 最后合并三部分得到符合要求的数据集。
内容的提问来源于stack exchange,提问作者Daniel Westergren
相关产品推荐
相关产品推荐

