I often have to compute new variables from existing data in a frame based on the condition of a factor variable.
Change After receiving 4 responses in 2 minutes, I realized that I had simplified my example. See below.
A 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 code like this
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 greater, and the calculations are more complicated, 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 to make this more beautiful with dplyr piping (or more)?
Edit In fact, I have more variable values ββto include in my calculations, and they are not simple sequential vectors, they are thousands of lines of measured data.
Here is my simple example with a second random value variable (again, this is 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 each condition. I understand that I can simplify this a bit.
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 like the switch example above will be even cleaner.