想要获取基于因子列与平均值偏离的值的数据框

问题描述

示例:

所以可以说我有这个数据框。

x = data.frame(factor = as.factor(c('a','a','b','c','c')),value1 = c(1,3,2,4,5,3),value2 = c(7,9,3))


    factor value1 value2
1      a      1      7
2      a      3      9
3      b      2      3
4      b      4      4
5      c      5      9
6      c      3      3

我知道如何获取每个因子的平均值,我使用这种方法

aggregate(x[,c(2,3)],list(x$factor),mean,na.rm = T )

这给了我以下输出

  Group.1 value1 value2
1       a      2    8.0
2       b      3    3.5
3       c      4    6.0

现在我该如何从原始数据框中的每个值中减去其因子的相应平均值。我正在使用的实际数据集很大,因此需要有一个不错的方法,我已经做到了,但是我使用了复杂的for循环。

所以我想要的输出是:

  factor value1 value2
1      a     -1   -1.0
2      a      1    1.0
3      b     -1   -0.5
4      b      1    0.5
5      c      1    3.0
6      c     -1   -3.0

任何帮助都会很棒。谢谢。

解决方法

dplyr解决方案

library(dplyr)
x %>% group_by(factor) %>% mutate(across(c(value1,value2),~. - mean(.)))

输出

# A tibble: 6 x 3
# Groups:   factor [3]
  factor value1 value2
  <fct>   <dbl>  <dbl>
1 a          -1   -1  
2 a           1    1  
3 b          -1   -0.5
4 b           1    0.5
5 c           1    3  
6 c          -1   -3  
,

您可以尝试这种dplyr方法:

library(dplyr)
#Data
x = data.frame(factor = as.factor(c('a','a','b','c','c')),value1 = c(1,3,2,4,5,3),value2 = c(7,9,3))
#Code
x <- x %>% group_by(factor) %>%
  mutate(Mv1=mean(value1),Mv2=mean(value2),value1=value1-Mv1,value2=value2-Mv2) %>% select(-c(Mv1,Mv2))

输出:

# A tibble: 6 x 3
# Groups:   factor [3]
  factor value1 value2
  <fct>   <dbl>  <dbl>
1 a          -1   -1  
2 a           1    1  
3 b          -1   -0.5
4 b           1    0.5
5 c           1    3  
6 c          -1   -3  
,

这是data.table

的解决方案
library("data.table")
setDT(x)
cols <- paste0("value",1:2)
x[,lapply(.SD,function(x) x - mean(x)),.SDcols=cols,by=factor]

library("data.table")
setDT(x)
x[,sweep(.SD,STATS=colMeans(.SD)),by=factor,.SDcols=2:3]