Search code examples
rconditional-statementsparentheses

Conditional statement in daa.R of the R "matchingMarkets" library


I am trying to get my head around daa.R, one of the functions in the matchingMarkets R library (links are to GitHub repositories). On lines 134-135, one finds the following if statement

if (0 %in% (c.hist[[j]] & any(c.prefs[ ,j]==proposers[k]))){  # if no history and proposer is on preference list
          c.hist[[j]][c.hist[[j]]==0][1] <- proposers[k]              # then accept
}

where c.hist and proposers are a list and c.prefs a matrix.

I am puzzled by the parentheses in the conditional statement. Instead of the above synthax, I would have opted for

if (0 %in% c.hist[[j]] & any(c.prefs[ ,j]==proposers[k]))

I don't understand how the original condition may work. How could R possibly check whether 0 is in (c.hist[[j]] & any(c.prefs[ ,j]==proposers[k]))?

I am a beginner in R, so I wanted to make sure I was not missing something and tried to replicate a similar synthax with other conditions such as,

> x = list(4,3)
> y = list(5,2)
> if (3 %in% (x & any(y == 5))){z = 8}

As I expected, I got an error message

 Error in x & any(y == 5) : operations are possible only for numeric, logical or complex types

whereas things go just fine when I write

if (3 %in% x & any(y == 5)){z = 8}

instead.

What am I missing? Why would the kind of conditional synthax I am puzzled by work in daa.R and not with the other conditions I tried?


Solution

  • When you ask R if 0 %in% x where x is a logical vector, R will first convert x to a numeric vector where FALSE becomes 0 and TRUE becomes 1. So essentially, asking if 0 %in% x is like asking if x contains any FALSE. This is arguably pretty bad practice. A better approach would be to test if any(!x) or !all(x). Worse, if x has length 1 as it seems to be the case here, you would just test if !x.

    In light of the contorted usage, you are raising a very good question: is the code doing what it really meant to do? In R, the %in% operator has higher precedence than & (see ?Syntax), thus these two statements are not the same:

    0 %in% (c.hist[[j]]) & any(c.prefs[ ,j]==proposers[k]))   # original code
    
    0 %in% c.hist[[j]] & any(c.prefs[ ,j]==proposers[k])      # what you suggested
    

    and we would need to look closely at what the code is supposed to be doing to decide if it is correct or wrong. I will just point out that you did not test your assumption properly: the error you got ("unexpected '{'") is because you forgot a closing parenthesis:

    if (3 %in% (x & any(y == 5)){z = 8}
    

    should be

    if (3 %in% (x & any(y == 5))){z = 8}