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

求层级数据特定分组归一化的优雅dplyr实现方式

符合dplyr风格的层级数据归一化优化方案

问题背景

我有层级数据,因变量为EucDistance,测量值按dog、spacing、stride分类。需要按以下方式归一化数据:

  • 计算每个dog下特定spacing(如100)对应的EucDistance平均值;
  • 用该平均值对每个dog的所有EucDistance测量值做归一化。

现有代码可实现需求,但分为两步且取值方式笨拙,不够符合dplyr风格,希望得到更优方案。

数据示例

> dff
      X Unnamed..0        dog spacing trial stride      dxreal       dyreal EucDistance
1     0          0    Adeline      80     1      1 -0.45589009  0.414136003   0.6159094
...(省略部分数据)
42   50          4     Bailey      80     4      5  1.25466959 -0.326264279   1.2963966

现有实现代码

test <- dff %>%
  group_by(dog,spacing) %>%
  mutate(grpMean=mean(EucDistance))

test2 <- test %>%
  group_by(dog) %>%
  mutate(normED=EucDistance/.data$grpMean[.data$spacing==100][1])

优化后的dplyr风格实现

以下几种方案均遵循dplyr管道式风格,避免了笨拙的索引取值,逻辑更清晰:

方案一:过滤关联法

先提取每个dog对应spacing=100的均值,再关联回原数据完成归一化:

dff_norm <- dff %>%
  group_by(dog, spacing) %>%
  summarise(mean_ed = mean(EucDistance), .groups = "drop_last") %>%
  filter(spacing == 100) %>%
  select(dog, mean_ed_100 = mean_ed) %>%
  left_join(dff, ., by = "dog") %>%
  mutate(normED = EucDistance / mean_ed_100) %>%
  select(-mean_ed_100) # 可选:移除临时辅助列

方案二:单管道内部分组计算

在dog分组内直接提取目标均值,无需额外关联操作:

dff_norm <- dff %>%
  group_by(dog, spacing) %>%
  mutate(grp_mean = mean(EucDistance)) %>%
  group_by(dog) %>%
  mutate(
    mean_ed_100 = first(grp_mean[spacing == 100]),
    normED = EucDistance / mean_ed_100
  ) %>%
  ungroup() %>%
  select(-grp_mean, -mean_ed_100) # 可选:移除临时辅助列

方案三:dplyr 1.1.0+专属优雅写法

利用reframe精准提取分组目标值,再映射到原数据:

mean_ed_100 <- dff %>%
  filter(spacing == 100) %>%
  group_by(dog) %>%
  reframe(mean_ed_100 = mean(EucDistance))

dff_norm <- dff %>%
  left_join(mean_ed_100, by = "dog") %>%
  mutate(normED = EucDistance / mean_ed_100) %>%
  select(-mean_ed_100)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 13:57:42