0
votes

I'm trying to create a conditional variable using mutate in dplyr which doesn't appear to be working for me. Please see example dataframe and combined score variable I attempt to create. Notice that the 3rd observation of the new variable 'combined.score' is not the sum of B, C and D. It appears that only the first observation is calculated and this value is used for each row observation.

What am I missing here? Would like a reason for why this is happening (not so much alternative code or a solution)

df <- 
  data.frame(B=c(1,0,0), 
             C=c(3,4,9), 
             D=c(1,1,0))

#A function to calculate stations whether there is a communication or process component or both
df <- df %>%
  mutate(combined.score = ifelse("B" %in% names(.) & "C" %in% names(.) & "D" %in% names(.), B + C + D,
                                 ifelse("B" %in% names(.) & "C" %in% names(.), B + C,
                                        B))) %>%
  mutate(combined.score.correct = B + C + D) 
1
notice that "B" %in% names(.) & "C" %in% names(.) & "D" %in% names(.) is either TRUE or FALSE; ifelse is best used for cases of vectors of logical values; what exactly are you trying to test for with this statement? - MichaelChirico
notice that rowSums(df) gives you exactly what you want as combined.score. - MichaelChirico
@MichaelChirico the first conditional would return 'TRUE' so I expect that it would calculate 'combined.score' = B + C + D. Much like the 'combined.score.correct' variable. I've used mutate - ifelse statements plenty of times for dataframes without a hitch, why is this situation special? - mkrasmus
@MichaelChirico: 'what exactly are you trying to test for this statement?' The ifelse statement itself is what I'm testing in the statement i.e., if "B", "C" & "D" exists, then calculate B + C + D. It doesn't do that, so why not? - mkrasmus

1 Answers

4
votes

The documentation for ifelse says:

ifelse returns a value with the same shape as test

Here test is "B" %in% names(df) & "C" %in% names(df) & "D" %in% names(df), which returns a 1-element vector

[1] TRUE

Therefore, the ifelse call returns a 1-element vector with only the first element of B + C + D, which is then recycled across the whole vector.