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

如何在R的tidyverse中按分组提取对应vt2的vo2值生成新列

问题:为R数据框添加对应分组的vt2的vo2值列

我知道这和之前的问题类似,但因涉及现有值,对我而言有所不同。以下是简化后的R数据框:

set.seed(2342)
df <- tibble(bp = rep(c("vt1", "vt2"), 4),
             id = rep(c(1, 2), each = 4, 1),
             alg_vt1 = rep(c("a", "b"), each = 2, 2),
             alg_vt2 = rep(c("a", "b"), 4)) %>% 
    mutate(vo2 = round(runif(nrow(.), 10, 20)),
           vo2 = if_else(bp == "vt2", vo2 * 2, vo2))

该数据框的样例如下:

bp  id  alg_vt1 alg_vt2 vo2
vt1 1   a       a       18
vt2 1   a       b       36
vt1 1   b       a       16
vt2 1   b       b       30
vt1 2   a       a       19
vt2 2   a       b       32
vt1 2   b       a       10
vt2 2   b       b       34

我希望生成一个新列vo2_vt2,其值为每个id、alg_vt1组合对应的vt2的vo2值,最终数据框应如下:

bp  id  alg_vt1 alg_vt2 vo2 vo2_vt2
vt1 1   a       a       18  36
vt2 1   a       b       36  36
vt1 1   b       a       16  30
vt2 1   b       b       30  30
vt1 2   a       a       19  32
vt2 2   a       b       32  32
vt1 2   b       a       10  34
vt2 2   b       b       34  34

我尝试过以下代码的多种变体,但后续内容要么报错,要么无法得到预期结果:

df %>% 
    group_by(id, alg_vt1, alg_vt2) %>% 
    mutate(vo2_vt2 = 

我知道有一些临时解决方法,但肯定存在tidyverse的标准解法,我感觉可以用filter()或pick()实现,但无法整合起来。


解决方案

你之前的核心问题是分组维度错误,应该按id和alg_vt1分组(每个分组包含对应vt1和vt2的行),然后提取分组内bp == "vt2"的vo2值并广播到整个分组即可:

library(tidyverse)

df %>%
  group_by(id, alg_vt1) %>%
  mutate(vo2_vt2 = vo2[bp == "vt2"]) %>%
  ungroup()

原理说明

  • 按id和alg_vt1分组后,每个分组内恰好包含一行bp == "vt2"的记录
  • vo2[bp == "vt2"]会提取该分组内vt2对应的vo2值,由于分组内的向量长度匹配,这个值会自动填充到分组内的所有行
  • 最后用ungroup()取消分组,避免后续操作受分组影响

如果需要通过关联映射的方式实现,也可以用表连接的方法:

# 先提取vt2的vo2值作为映射表
vt2_map <- df %>%
  filter(bp == "vt2") %>%
  select(id, alg_vt1, vo2_vt2 = vo2)

# 连接原表得到结果
df %>%
  left_join(vt2_map, by = c("id", "alg_vt1"))

两种方法都能得到你预期的结果,第一种更简洁高效。

内容的提问来源于stack exchange,提问作者a.hesse

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 18:50:31