user3708098
user3708098

Reputation: 43

Subtraction within Groups using R

I have been struggling to find the best way to do this subtraction within groups. I have data frame containing a long list of samples (Sample), each one treated with different conditions (condition), resulting in a measured value (value). I would like to subtract each condition from condition A resulting in dValue.

    Sample   condition      value    dValue
    var1         A            12       0
    var1         B            14      -2
    var1         C            15      -3
    var2         A            20       0
    var2         B            19       1
    var2         C            19       1
    var3         A            50       0
    var3         B            51      -1
    var3         C            48       2

What would be the best way to accomplish this using R? I can accomplish this easily in excel and have been getting my data to this point, switching to Excel, then back to R and I know there is a better way.

Upvotes: 4

Views: 5803

Answers (3)

Arun
Arun

Reputation: 118799

Assuming your dataset is called dat, here's a couple of data.table solutions:

Method 1:

require(data.table) ## >= 1.9.2
setDT(dat)[, dValue := value[condition == "A"] - value, by=Sample]

Method 2:

require(data.table) ## >= 1.9.2
setkey(setDT(dat), Sample)
dat[dat[condition == "A"], dValue := i.value-value]

#    Sample condition value dValue
# 1:   var1         A    12      0
# 2:   var1         B    14     -2
# 3:   var1         C    15     -3
# 4:   var2         A    20      0
# 5:   var2         B    19      1
# 6:   var2         C    19      1
# 7:   var3         A    50      0
# 8:   var3         B    51     -1
# 9:   var3         C    48      2

Upvotes: 2

talat
talat

Reputation: 70266

You can also do that with dplyr:

require(dplyr)

df %.% 
   group_by(Sample) %.% 
   mutate(dValue = value[condition == "A"] - value)

#  Sample condition value dValue
#1   var1         A    12      0
#2   var1         B    14     -2
#3   var1         C    15     -3
#4   var2         A    20      0
#5   var2         B    19      1
#6   var2         C    19      1
#7   var3         A    50      0
#8   var3         B    51     -1
#9   var3         C    48      2

Upvotes: 6

Jilber Urbina
Jilber Urbina

Reputation: 61154

Try this

> transform(df, dValue=ave(value, Sample, FUN=function(x) c(0, x[1]-x[-1])))
  Sample condition value dValue
1   var1         A    12      0
2   var1         B    14     -2
3   var1         C    15     -3
4   var2         A    20      0
5   var2         B    19      1
6   var2         C    19      1
7   var3         A    50      0
8   var3         B    51     -1
9   var3         C    48      2

I'm assuming df looks like this

  Sample condition value
1   var1         A    12
2   var1         B    14
3   var1         C    15
4   var2         A    20
5   var2         B    19
6   var2         C    19
7   var3         A    50
8   var3         B    51
9   var3         C    48

Upvotes: 1

Related Questions