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?
Edited to reflect some notes from the comments
Assuming that
Condition
is a factor, you could do this:which makes use of fairly quick vectorized multiplication. And obviously, wrapping this in
with
isn't strictly necessary, it's just what popped out of my brain. Also note the subsetting comment below by Backlin.More globally, remember that every subsetting you can do with
subset
you can also do with[
, and crucially,[
support assignment via[<-
. So if you want to alter a portion of a data frame or matrix, you can always use this type of idiom:assuming of course that
<replacement values>
is the same dimension as your subset ofdf
. It may work otherwise, but you will run afoul of R's recycling rules and R may kick back a warning.Here's a non-vectorized, but easy to understand solution:
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 multiplicationTRUE
andFALSE
are converted to1
and0
, respectively. We can add theouter
results because the conditions are non-overlapping and theFALSE
elements will be zero.Or by vector multiplication