I frequently have to calculate new variables from existing ones in a data frame based on a condition of a factor variable.
Edit Getting 4 answers in like 2 mins, I realised I have oversimplified my example. Please see below.
Simple example:
df <- data.frame(value=c(1:5),class=letters[1:5])
df
value class
1 a
2 b
3 c
4 d
5 e
I can use such code
df %>%
mutate(result=NA) %>%
mutate(result=ifelse(class=="a",value*1,result)) %>%
mutate(result=ifelse(class=="b",value*2,result)) %>%
mutate(result=ifelse(class=="c",value*3,result)) %>%
mutate(result=ifelse(class=="d",value*4,result)) %>%
mutate(result=ifelse(class=="e",value*5,result))
to perform conditional calculations on my variables, resulting in
value class result
1 a 1
2 b 4
3 c 9
4 d 16
5 e 25
As in reality the number of classes is larger and the calculations are more complex, however, I would prefer something cleaner, like this
df %>%
mutate(results=switch(levels(class),
"a"=value*1,
"b"=value*2,
"c"=value*3,
"d"=value*4,
"e"=value*5))
which obviously doesn't work
Error in switch(levels(1:5), a = 1:5 * 1, b = 1:5 * 2, c = 1:5 * 3, d = 1:5 * :
EXPR must be a length 1 vector
Is there a way I can do this more nicely with dplyr piping (or else)?
Edit In reality, I have more value variables to include in my calculations and they are not simple consecutive vectors, they are thousands of rows of measured data.
Here my simple example with a second random value variable (again, it's more in my real data)
df <- data.frame(value1=c(1:5),value2=c(2.3,3.6,7.2,5.6,0),class=letters[1:5])
value1 value2 class
1 2.3 a
2 3.6 b
3 7.2 c
4 5.6 d
5 0.0 e
and my calculations are different for every condition. I understand I can simplify somewhat like this
df %>%
mutate(result=NA,
result=ifelse(class=="a",value1*1,result),
result=ifelse(class=="b",value1/value2*4,result),
result=ifelse(class=="c",value2*3.57,result),
result=ifelse(class=="d",value1+value2*2,result),
result=ifelse(class=="e",value2/value1/5,result))
A working solution similar to the above switch example would be even cleaner, though.