Aru Bhardwaj
Aru Bhardwaj

Reputation: 55

How to subtract value of one group from other groups in R

I am trying to subtract the value of one group from another. I am hoping to use tidyverse

structure(list(A = c(1, 1, 1, 2, 2, 2, 3, 3, 3), group = c("a", 
"b", "c", "a", "b", "c", "a", "b", "c"), value = c(10, 11, 12, 
11, 40, 23, 71, 72, 91)), class = "data.frame", row.names = c(NA, 
-9L))

That is my data, and I want to subtract all values of group A from B and C, and store the difference in one variable.

Upvotes: 1

Views: 1274

Answers (2)

AnilGoyal
AnilGoyal

Reputation: 26218

baseR solution

df$new <- df$value - ave(df$value, df$A, FUN = function(x) mean(x[df$group == 'a'], na.rm = T) )

> df
  A group value new
1 1     a    10   0
2 1     b    11   1
3 1     c    12   2
4 2     a    11   0
5 2     b    40  29
6 2     c    23  12
7 3     a    71   0
8 3     b    72   1
9 3     c    91  20

dplyr method (assumption there is not more than one a value per group, else R will confuse which value to substract and result in error)

df %>% group_by(A) %>% mutate(new = ifelse(group != 'a', value - value[group == 'a'], value) )

# A tibble: 9 x 4
# Groups:   A [3]
      A group value   new
  <dbl> <chr> <dbl> <dbl>
1     1 a        10    10
2     1 b        11     1
3     1 c        12     2
4     2 a        11    11
5     2 b        40    29
6     2 c        23    12
7     3 a        71    71
8     3 b        72     1
9     3 c        91    20

or if you want to change all values

df %>% group_by(A) %>% mutate(new = value - value[group == 'a'] )

# A tibble: 9 x 4
# Groups:   A [3]
      A group value   new
  <dbl> <chr> <dbl> <dbl>
1     1 a        10     0
2     1 b        11     1
3     1 c        12     2
4     2 a        11     0
5     2 b        40    29
6     2 c        23    12
7     3 a        71     0
8     3 b        72     1
9     3 c        91    20

Upvotes: 2

John Girardot
John Girardot

Reputation: 371

I only used data.table rather than data.frame because I'm more familiar.

library(data.table)

data <- setDT(structure(list(A = c(1, 1, 1, 2, 2, 2, 3, 3, 3), group = c("a", 
 "b", "c", "a", "b", "c", "a", "b", "c"), value = c(10, 11, 12, 
  11, 40, 23, 71, 72, 91)), class = "data.frame", row.names = c(NA,-9L)))

for (i in 1:length(unique(data$A))){
  data[A == i, substraction := data[A == i, 'value'] - data[A == i & group == 'a', value]]
}

enter image description here

Upvotes: 2

Related Questions