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

在R中按组对两个DataFrame的向量执行减法运算

按分组对DataFrame进行逐行向量减法运算

需求说明

我有两个R DataFrame:

  • 主数据集df_repr:包含多列数值特征,以及标记分组的group因子列
  • 分组向量集to_subtract:行数等于主数据集的唯一分组数,每行对应一个分组的向量,需要用主数据集中对应分组的每行数据减去该分组的向量

示例数据

主数据集

df_repr <- structure(list(f1 = c(-3.9956064225704, 
-0.52380279948658, 0.61089389331505, -3.47273625634875, -4.486918671214, 
-6.1761970731672, -4.62305749757367, -4.42540643005429, -3.61613137597131, 
-3.29821425516253), f2 = c(-1.57918114753228, 
-4.10523012500727, -1.80270009366593, -0.00905317702835884, -0.899585192079915, 
-2.89341515186212, 0.0132542126386332, -3.32639898550135, -0.867793877742314, 
0.0911950321630834), f3 = c(-6.02532301769732, 
-4.90073348094302, -3.73159604513274, -3.55290209472808, -6.63194560195811, 
2.69409789701296, -4.17675978927128, -3.84141885970095, -1.20571283849034, 
1.54287440902102), group = structure(c(1L, 1L, 1L, 1L, 1L, 
2L, 2L, 2L, 2L, 2L), .Label = c("A", "B"), class = "factor")), class = c("tbl_df", "tbl", 
"data.frame"), row.names = c(NA, -10L))

分组向量集

to_subtract <- structure(list(group = structure(1:2, .Label = c("A", 
"B"), class = "factor"), f1 = c(-2.78048744402161, 
-2.33583431665818), f2 = c(-2.56086962108741, 
-0.689157827347865), f3 = c(-3.60224982918457, 
-0.782365376308658)), row.names = c(NA, -2L), class = c("tbl_df", 
"tbl", "data.frame"))

尝试的代码及报错

我尝试用以下代码实现,但出现错误:

df_repr %>%
  group_by(group) %>%
  mutate(across(where(is.numeric),
         ~ . - to_subtract[to_subtract$group == unique(.$group), -1]))

报错信息:

Error in `mutate()`:
ℹ️ In argument: `across(...)`.
ℹ️ In group 1: `group = A`.
Caused by error in `across()`:
! Can't compute column `f1`.
Caused by error in `f1$group`:
! $ operator is invalid for atomic vectors

错误原因:to_subtract[to_subtract$group == unique(.$group), -1]返回的是DataFrame对象,而across中.指代的是当前列的原子向量,向量与DataFrame直接做减法会导致维度不兼容,触发报错。

解决方案

方法1:合并后逐列计算

先将分组向量集合并到主数据集,再对每个特征列减去对应分组的向量值:

library(dplyr)

df_repr %>%
  left_join(to_subtract, by = "group", suffix = c("", "_sub")) %>%
  mutate(across(starts_with("f"), ~ . - get(paste0(cur_column(), "_sub"))),
         .keep = "unused")

方法2:分组后提取原子向量

分组后,从to_subtract中提取当前分组的数值向量并转成原子向量,再进行减法:

df_repr %>%
  group_by(group) %>%
  mutate(across(where(is.numeric),
                ~ . - unlist(to_subtract[to_subtract$group == cur_group()$group, -1]))) %>%
  ungroup()

方法3:矩阵索引匹配

将分组向量集转为矩阵,通过匹配分组索引提取对应向量进行减法:

sub_mat <- as.matrix(to_subtract[, -1])
idx <- match(df_repr$group, to_subtract$group)

df_repr %>%
  mutate(across(where(is.numeric), ~ . - sub_mat[idx, cur_column()]))

期望输出

# # A tibble: 10 × 4
#       f1     f2      f3 group
#    <dbl>  <dbl>   <dbl> <fct>
#  1 -1.22   0.982 -2.42   A    
#  2  2.26  -1.54  -1.30   A    
#  3  3.39   0.758 -0.129  A    
#  4 -0.692  2.55   0.0493 A    
#  5 -1.71   1.66  -3.03   A    
#  6 -3.84  -2.20   3.48   B    
#  7 -2.29   0.702 -3.39   B    
#  8 -2.09  -2.64  -3.06   B    
#  9 -1.28  -0.179 -0.423  B    
# 10 -0.962  0.780  2.33   B 

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 15:39:58