-1

so I am trying to create a binary variable that shows whether an MP voted as their constituency did

basically meaning I want a new column if constituency voted yes and MP also votes yes (or Aye in the case of my variable) the new column shows that constituency as the MP having voted with their constituency

This is the code I have so far, but I keep getting errors, does anyone possibly know a more effective way to do this? any help greatly appreciated!

Comparison_2016_2ndRef$MP_representativeness <-if (Comparison_2016_2ndRef$Second_Ref == "Yes" & Comparison_2016_2ndRef$voteOn2Ref == "Aye") {
  Comparison_2016_2ndRef$MPrepresentativeness <- "Voted With Constituency";
  
} else if(Comparison_2016_2ndRef$Second_Ref == "No" & Comparison_2016_2ndRef$voteOn2Ref == "No") {
  Comparison_2016_2ndRef$MPrepresentativeness <- "Voted With Constituency";
  
} else if(Comparison_2016_2ndRef$Second_Ref == "Yes" & Comparison_2016_2ndRef$voteOn2Ref == "No") {
  Comparison_2016_2ndRef$MPrepresentativeness <- "Voted Against Constituency";
  
} else if(Comparison_2016_2ndRef$Second_Ref == "Yes" & Comparison_2016_2ndRef$voteOn2Ref == "No"){
  Comparison_2016_2ndRef$MPrepresentativeness <- "Voted Against Constituency";
}
else {Comparison_2016_2ndRef$MPrepresentativeness <- "Voted Against Constituency";}
  • What errors are you getting? Your more likely to get help if you can produce a minimal, reproducible example – Captain Hat Apr 13 '21 at 15:14
  • 1
    Off the top of my head I would be considering `ifelse()`. Or run `dplyr::mutate()` with `dplyr::case_when()` (or even `base::replace()`) to turn your character variables into logicals before analysing them – Captain Hat Apr 13 '21 at 15:16
  • 1
    @CaptainHat, `case_when` still calcs the LHS conditionals as vectors, I don't think it defaults to a `rowwise()` workflow by itself. so `mutate`/`case_when` does not resolve the issue with `if` and length != 1. – r2evans Apr 13 '21 at 15:28
  • It would be easier to help if you create a small reproducible example along with expected output. Read about [how to give a reproducible example](http://stackoverflow.com/questions/5963269). – Ronak Shah Apr 14 '21 at 00:02

1 Answers1

0

This is likely a dupe of one of: if-else vs ifelse with lists or How to vectorize from if to ifelse with multiple statements?, though multiple nests of ifelse can be annoying/problematic. In fact, past 2-deep, I typically move away from ifelse.

If all you need to return is ..With.. or ..Against.., though, then this can be resolved in a single ifelse statement.

with(Comparison_2016_2ndRef, 
  ifelse( (Second_Ref == "Yes" & voteOn2Ref == "Aye") |
            (Second_Ref == "No" & voteOn2Ref == "No"),
         "Voted With Constituency", "Voted Against Constituency") )

Walk-through:

  • with(Comparison_2016_2ndRef, ...) makes that frame the working environment for the duration of that call, so every symbol/variable inside with is first resolved against variables within the dataframe, then normal searching. This is certainly not required, but IMO it makes the code much easier to read. (Its utility is not great if there are only one or two symbols, but increases quickly.)
  • && is a simple length-1 "AND" operator that allows short-circuiting, but it does not allow vectors. & is a vectorized "AND" operator, meaning c(T,F,T) & c(T,T,T) & c(F,F,T) returns c(F,F,T), etc. It is often not appropriate within if, but it is very useful inside ifelse. Similarly, || (len-1) and | (vectorized) "OR".
  • We can combine combinations that lead to "..With.." into one vector instead of independent comparison, ergo the unified conditional.
  • I assume the "if you aren't with me, you're against me" hyperbole here, so if they didn't vote with then they voted against. I don't know your data, but if you have NA values (perhaps they did not vote at all for some reason), then you'll need to extend this logic slightly.
  • Speaking of NA, if any one value is NA, then the returned string will be NA as well. You can clean that up later to be "unk" or some other indicator.
r2evans
  • 141,215
  • 6
  • 77
  • 149