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

在R中按id分组计算各数值列after与before的差值

问题描述

我有一个结构如下示例的数据框:

df <- data.frame(rbind(c("Sample1_x2", 10, 23, 6, 5, "Sample1", "after"),
            c("Sample2_x2", 8, 53, 22, 52, "Sample2", "after"),
            c("Sample1_x1", 12, 2, 44, 15, "Sample1", "before"),
            c("Sample3_x1", 27, 46, 16, 65, "Sample3", "before"),
            c("Sample2_x1", 41, 44, 27, 25, "Sample2", "before"),
            c("Sample3_x2", 5, 38, 9, 29, "Sample3", "after")))
colnames(df) <- c("name", "alpha", "beta", "gamma", "rho", "id", "group")
df <- tibble::column_to_rownames(df, var = "name")
df
           alpha beta gamma rho      id  group
Sample1_x2   10   23    6    5 Sample1  after
Sample2_x2    8   53   22   52 Sample2  after
Sample1_x1   12    2   44   15 Sample1 before
Sample3_x1   27   46   16   65 Sample3 before
Sample2_x1   41   44   27   25 Sample2 before
Sample3_x2    5   38    9   29 Sample3  after

我希望按id分组,对每个数值列计算after - before的差值,得到如下目标结果:

id   alpha  beta  gamma    rho       
Sample1      -2    21    -38    -10
Sample2     -33     9     -5     27    
Sample3     -22    -8     -7    -36

我尝试使用dplyr::group_by(id, group),但在mutate()部分无法成功计算每个样本的差值,恳请提供帮助。

解决方案

方法1:转宽格式后计算差值

先将group的before和after转为独立列,再直接做减法,逻辑直观清晰:

library(dplyr)
library(tidyr)

df %>%
  # 先把字符型数值列转为数值类型
  mutate(across(c(alpha, beta, gamma, rho), as.numeric)) %>%
  # 按id分组,将group转为列名,数值列作为对应值
  pivot_wider(names_from = group, values_from = c(alpha, beta, gamma, rho)) %>%
  # 计算after与before的差值
  mutate(
    alpha = alpha_after - alpha_before,
    beta = beta_after - beta_before,
    gamma = gamma_after - gamma_before,
    rho = rho_after - rho_before
  ) %>%
  # 保留目标列并设置id为行名
  select(id, alpha, beta, gamma, rho) %>%
  tibble::column_to_rownames(var = "id")

方法2:分组后直接汇总计算

无需转换格式,直接按id分组,在summarise中提取对应组的数值做减法:

library(dplyr)

df %>%
  mutate(across(c(alpha, beta, gamma, rho), as.numeric)) %>%
  group_by(id) %>%
  summarise(
    alpha = first(alpha[group == "after"]) - first(alpha[group == "before"]),
    beta = first(beta[group == "after"]) - first(beta[group == "before"]),
    gamma = first(gamma[group == "after"]) - first(gamma[group == "before"]),
    rho = first(rho[group == "after"]) - first(rho[group == "before"])
  ) %>%
  tibble::column_to_rownames(var = "id")

关键注意点

  • 原数据框的数值列是字符类型,必须先转为数值类型才能进行算术运算,否则会得到错误的字符拼接结果。
  • 两种方法均可得到目标结果,可根据个人习惯选择。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 14:44:55