Добавить новый столбец на основе агрегации из двух других столбцов - PullRequest
1 голос
/ 21 марта 2020

С фреймом данных

(d <- data.frame(x = c(22, 2, 14, 3, 50, 11), E= rep(c('C','D'), each=3), F = rep(c('A','B'), 3)))
   x E F
1 22 C A
2  2 C B
3 14 C A
4  3 D B
5 50 D A
6 11 D B

Я хочу агрегировать столбец «x» для каждого уровня фактора «F» следующим образом:

(y <- aggregate(x ~ F, d, function(x) x-mean(x)))
  F        x.1        x.2        x.3
1 A  -6.666667 -14.666667  21.333333
2 B  -3.333333  -2.333333   5.666667

Что такое элегантный способ использовать команду, чтобы вышеуказанный агрегированный результат можно было прикрепить к исходному кадру данных, как показано ниже:

   x E F  y
1 22 C A  -6.666667
2  2 C B  -3.333333
3 14 C A -14.666667
4  3 D B  -2.333333
5 50 D A  21.333333
6 11 D B   5.666667

Ответы [ 2 ]

4 голосов
/ 21 марта 2020

Ее уже в пути. Вы определяете группы, используя F. Для каждой группы вы хотите вычесть среднее значение из x.

library(dplyr)
group_by(d, F) %>% 
mutate(result = x - mean(x))

      x E     F     result
  <dbl> <fct> <fct>  <dbl>
1    22 C     A      -6.67
2     2 C     B      -3.33
3    14 C     A     -14.7 
4     3 D     B      -2.33
5    50 D     A      21.3 
6    11 D     B       5.67

Если вы используете пакет data.table, вы можете добиться того же самого следующим образом.

library(data.table)
setDT(d)[, result := x - mean(x), by = F][]

    x E F     result
1: 22 C A  -6.666667
2:  2 C B  -3.333333
3: 14 C A -14.666667
4:  3 D B  -2.333333
5: 50 D A  21.333333
6: 11 D B   5.666667
1 голос
/ 21 марта 2020

В базе R мы можем использовать ave, чтобы применить функцию к каждой группе, сохраняя количество строк одинаковым.

d$y <- with(d, x - ave(x, F))
#Explicitly mentioning the function name
#d$y <- with(d, x - ave(x, F, FUN = mean))
d

#   x E F          y
#1 22 C A  -6.666667
#2  2 C B  -3.333333
#3 14 C A -14.666667
#4  3 D B  -2.333333
#5 50 D A  21.333333
#6 11 D B   5.666667

ave имеет аргумент по умолчанию FUN как mean.

...