Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiply various subsets of a data frame by different vectors

I would like to multiply several columns in my data frame by a vector of values. The specific vector of values changes depending on the value in another column.

--EDIT--

What if I make the data set more complicated, i.e., more than 2 conditions and the conditions are randomly shuffled around the data set?

Here is an example of my data set:

df=data.frame(
  Treatment=(rep(LETTERS[1:4],each=2)),
  Species=rep(1:4,each=2),
  Value1=c(0,0,1,3,4,2,0,0),
  Value2=c(0,0,3,4,2,1,4,5),
  Value3=c(0,2,4,5,2,1,4,5),
  Condition=c("A","B","A","C","B","A","B","C")
  )

Which looks like:

 Treatment Species Value1 Value2 Value3 Condition
     A       1      0      0      0         A
     A       1      0      0      2         B 
     B       2      1      3      4         A
     B       2      3      4      5         C
     C       3      4      2      2         B
     C       3      2      1      1         A
     D       4      0      4      4         B
     D       4      0      5      5         C

If Condition=="A", I would like to multiply columns 3-5 by the vector c(1,2,3). If Condition=="B", I would like to multiply columns 3-5 by the vector c(4,5,6). If Condition=="C", I would like to multiply columns 3-5 by the vector c(0,1,0). The resulting data frame would therefore look like this:

 Treatment Species Value1 Value2 Value3 Condition
     A       1      0      0      0         A
     A       1      0      0     12         B 
     B       2      1      6     12         A
     B       2      0      4      0         C
     C       3     16     10     12         B
     C       3      2      2      3         A
     D       4      0     20     24         B
     D       4      0      5      0         C

I have tried subsetting the data frame and multiplying by the vector:

t(t(subset(df[,3:5],df[,6]=="A")) * c(1,2,3))

But I can't return the subsetted data frame to the original. Is there any way to perform this operation without subsetting the data frame, so that other columns (e.g., Treatment, Species) are preserved?

like image 752
jslefche Avatar asked Dec 09 '22 07:12

jslefche


1 Answers

Here's a fairly general solution that you should be able to adapt to fit your needs.

Note the first argument in the outer call is a logical vector and the second is numeric, so before multiplication TRUE and FALSE are converted to 1 and 0, respectively. We can add the outer results because the conditions are non-overlapping and the FALSE elements will be zero.

multiples <-
  outer(df$Condition=="A",c(1,2,3)) +
  outer(df$Condition=="B",c(4,5,6)) +
  outer(df$Condition=="C",c(0,1,0))

df[,3:5] <- df[,3:5] * multiples
like image 89
Joshua Ulrich Avatar answered Jan 13 '23 21:01

Joshua Ulrich