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

如何在数据框同日内识别最近的x_location观测值及对应信息

按日分组获取同组内最近的x_location及对应名称(同名称仅参与一次排名)

问题背景

我有一个包含Day、Name、x_location列的数据框(例如周二的Harry出现了两次),需要实现:

  • 按Day分组
  • 为每条观测生成最近、第二近、第三近的x_location及其对应的Name列
  • 注意:同一日内的同一Name仅参与一次近邻排名(即周二的Harry两条记录,计算近邻时只取一次Harry的x_location)

之前尝试用which.min实现,但代码完全无法得到预期结果:

library(tidyverse)

dat1 <- dat %>%
  group_by(Day) %>%
  mutate(x_closest = which.min(abs(x_location -x_location)))

原代码问题分析

  1. abs(x_location -x_location)计算的是自身与自身的距离,结果全为0,which.min只会返回每组的第一个行号,完全不符合需求
  2. 没有处理同一Name去重的逻辑,也无法生成多阶近邻(最近、第二近、第三近)

解决方案代码

首先构造原始示例数据(与你提供的结构一致):

dat <- tibble(
  Day = c("Monday", "Monday", "Monday", "Monday", "Monday", 
          "Tuesday", "Tuesday", "Tuesday", "Tuesday", "Tuesday", "Tuesday"),
  Name = c("Steve", "Joe", "Brian", "Mike", "Harry", 
           "Steve", "Joe", "Brian", "Mike", "Harry", "Harry"),
  x_location = c(2.5, 6, 4.5, 8, 5, 1, 3.5, 4, 9.5, 10, 10)
)

以下是实现需求的完整代码:

library(tidyverse)

result <- dat %>%
  group_by(Day) %>%
  group_modify(function(.x, .y) {
    # 生成当前日期下唯一的Name-x_location参考集,去重同Name
    unique_ref <- .x %>% distinct(Name, .keep_all = TRUE)
    
    .x %>%
      rowwise() %>%
      mutate(
        # 计算当前行到参考集每个点的距离,过滤自身后排序取前3
        nearest = list(
          unique_ref %>%
            filter(Name != cur_data()$Name) %>%
            mutate(distance = abs(x_location - cur_data()$x_location)) %>%
            arrange(distance) %>%
            slice_head(n = 3) %>%
            select(x_location, Name)
        )
      ) %>%
      ungroup() %>%
      # 将list列拆分为多列
      unnest_wider(nearest, names_sep = "_") %>%
      # 重命名列以匹配需求
      rename(
        closest_x = x_location_1,
        closest_x_name = Name_1,
        second_closest_x = x_location_2,
        second_closest_name = Name_2,
        third_closest_x = x_location_3,
        third_closest_name = Name_3
      )
  }) %>%
  ungroup()

# 查看最终结果
print(result)

代码逻辑说明

  1. group_by(Day) + group_modify:按日期分组处理每个子数据集
  2. distinct(Name, .keep_all = TRUE):生成每个日期下的唯一Name-x_location组合,确保同一名称仅参与一次近邻计算
  3. rowwise():逐行处理每条原始记录,计算当前行到参考集中所有点的距离,过滤掉自身后按距离排序取前3个
  4. unnest_wider:将存储近邻结果的list列拆分为多列,再通过rename调整列名以匹配需求

运行后得到的结果与你提供的目标数据框结构完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 10:45:41