You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R语言按treatment筛选最接近目标stage值的唯一观测值问题

按组筛选最接近目标值的唯一观测

原始数据集

data_a <- read.csv(text = "
date,treatment,stage
1,a,1
2,a,10
3,a,20
4,a,30
5,a,60
6,a,70
7,a,89
8,a,91
9,a,92
1,b,1
2,b,10
3,b,20
4,b,30
5,b,59.8
6,b,60.2
7,b,88.8
8,b,90.2
9,b,92
1,c,1
2,c,10
3,c,20
4,c,60
5,c,66
6,c,70
7,c,80
8,c,85
9,c,85")

需求说明

在每个treatment分组内,为目标值10、60、89分别筛选出stage值最接近的唯一观测:

  • 若存在精确匹配的stage值,直接选取该观测
  • 若有多个观测与目标值的差值相同,仅保留其中一个(参考期望输出,选取date较小的观测)

现有代码问题

原代码使用多条件筛选,当多个观测与目标值的绝对差值相等时,会将所有符合条件的观测都保留,不符合“唯一观测”的要求:

filtered_data <- data_a %>%
  group_by(treatment) %>%
  filter(abs(stage - 10) == min(abs(stage - 10)) |
         abs(stage - 60) == min(abs(stage - 60)) |
         abs(stage - 89) == min(abs(stage - 89)))

解决方案

通过对每个分组和每个目标值单独处理,找到最接近的观测后合并结果。使用purrr::map_dfr遍历目标值,结合slice_min在差值最小时选取date最小的观测:

library(dplyr)
library(purrr)

targets <- c(10, 60, 89)

filtered_data <- map_dfr(targets, function(target) {
  data_a %>%
    group_by(treatment) %>%
    mutate(diff = abs(stage - target)) %>%
    slice_min(order_by = diff, n = 1, with_ties = FALSE) %>%
    select(-diff)
}) %>%
  arrange(treatment, date)

验证输出结果与期望一致:

print(filtered_data)
#   date treatment stage
# 1    2         a 10.0
# 2    5         a 60.0
# 3    7         a 89.0
# 4    2         b 10.0
# 5    5         b 59.8
# 6    7         b 88.8
# 7    2         c 10.0
# 8    4         c 60.0
# 9    8         c 85.0

代码说明

  • map_dfr:遍历每个目标值,处理后按行合并结果
  • mutate(diff = abs(stage - target)):计算每个观测与当前目标值的绝对差值
  • slice_min(order_by = diff, n = 1, with_ties = FALSE):在每个分组内选取差值最小的1个观测,with_ties = FALSE确保即使有多个相同差值的观测,也只保留原数据中靠前的(即date较小的)
  • arrange(treatment, date):最后按分组和日期排序,与期望输出格式一致

内容的提问来源于stack exchange,提问作者Giuseppe Petri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 08:03:30