Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Conceptual difference between three codes: if/if/if, if/else if/else if, if/else if/else

    Hello,
    I don't have a data problem in particular. I'm trying to learn about how Stata works and I find myself a bit puzzled by the if command. I get there's a difference between the if command and an if qualifier, but it's hard for me to understand the difference between :

    1) a series of -if- commands

    2) an if command, then a series of -else if- commands until the end,

    3) an if command, then a series of -else if-, and then an -else- command at the end

    It may be an obvious distinction, but I would appreciate if someone would explain it to me like I'm a 6 year old child

    Let's take an example. I want to rename a variable based on the color of the thing it contains as a value.

    Code:
    * Example generated by -dataex-. For more info, type help dataex
    clear
    input str10(var1 var2 var3)
    "sea" "grass" "wood"
    end
    The three following codes produce the same results :

    Code:
    foreach var of varlist * {
        
        
    local a = strpos(`var', "sea")
    local b = strpos(`var', "grass")
    local c = strpos(`var', "wood")
    
        if `a' > 0 {
        rename `var' blue
    }
    
        if `b' > 0 {
        rename `var' green
        }
        
        if `c' > 0 {
        rename `var' brown
        }
    }
    Code:
    foreach var of varlist * {
        
        
    local a = strpos(`var', "sea")
    local b = strpos(`var', "grass")
    local c = strpos(`var', "wood")
    
        if `a' > 0 {
        rename `var' blue
    }
    
        else if `b' > 0 {
        rename `var' green
        }
        
        else if `c' > 0 {
        rename `var' brown
        }
    }
    Code:
    foreach var of varlist * {
        
        
    local a = strpos(`var', "sea")
    local b = strpos(`var', "grass")
    local c = strpos(`var', "wood")
    
        if `a' > 0 {
        rename `var' blue
    }
    
        else if `b' > 0 {
        rename `var' green
        }
        
        else rename `var' brown
        
    }
    Code:
    . list, clean
    
           blue   green   brown  
      1.    sea   grass    wood
    Maybe that was just luck, but if it is I would like someone to explain me how it is luck and when should I use each of those different lines. Thanks for this very cool software !
    Last edited by Thomas Brot; 10 Feb 2023, 06:58.

  • #2
    The example is not ideal to discuss the issues because you're phrasing it in terms of data and there is only one observation in the data. Hence by accident what almost always bites a programmer doesn't bite here.

    So for example


    Code:
    local a = strpos(`var', "sea")
    will always be interpreted as

    Code:
    local a = strpos(`var'[1], "sea")

    which is fine here, but not usually.

    That is the main difference between the if qualifier and the if command. The if qualifier will get evaluated for each observation and in general sometimes it will be true and sometimes it will be false. (Pedantic note: sometimes here includes the limiting case of not at all.)

    But the if command is evaluated just once and nothing about referring to a variable fires up machinery that loops over observations. On the contrary Stata will only look at the first observation. I think that's true of most programming languages, although SAS may have an exception. (Cue people who have used SAS more than I have, which means ever.)

    However, that is not what you're asking -- but I spell it out because it is often found puzzling. Your puzzlement is different. In any programming context, the three will give the same results because it so happens with your examples that one and only one statement is true each time round the loop. All codes lead to the right answer eventually. Other way round, what do you expect to be different here?

    Comment


    • #3
      In the silly examples that follow, I consider the if command (as opposed to the if qualifier).

      Consider the difference between

      Code:
      if 42 > 0 {
          display "first condition is true"
      }
      if 42 > 1  {
          display "second condition is also true"
      }
      and

      Code:
      if 42 > 0 {
          display "first condition is true"
      }
      else if 42 > 1  {
          display "second condition is also true"
      }
      Rarely do you ever want the former.

      The second approach, i.e., if, followed by else if statements does not explicitly cover the case in which none of the conditions is true. This is often considered bad programming style; even if all possible cases are covered, it is safer to code something like

      Code:
      if 42 < 0 {
          display "first condition is true"
      }
      else if 42 < 1  {
          display "second condition is true"
      }
      else {
          display "This should not happen! I must have missed something."
      }

      Comment


      • #4
        I hope to add a bit to the already excellent answers above:

        1) a series of -if- commands - You should use this if you want to test a series of conditions that are not mutually exclusive, meaning that several or all of the conditions can be true simultaneously.

        2) an if command, then a series of -else if- commands until the end - You should use this if you want to test a series of conditions that are mutually exclusive, meaning that if one condition is true, the rest are false. Even in cases where you account for every conceivable possibility explicitly, it is still conventional to end with an else block. You could get the same result for mutually exclusive conditions with a series of if statements, but it is less efficient than an if-else-if statement, because if one condition in the if-else-if statement turns out to be true, the program can skip executing every block of code that follows.

        3) an if command, then a series of -else if-, and then an -else- command at the end - Use this to test a series of conditions that are mutually exclusive. Like Daniel says in #3, It is good practice to use else, particularly if you haven't comprehensively accounted for every possible case. The third block above is how I often prefer to use an else statement: as a kind of default catch all to detect edge cases I haven't accounted for. Techniques like this, that automatically check the correctness of your code can be subtle, but very important.
        Last edited by Daniel Schaefer; 10 Feb 2023, 10:29.

        Comment

        Working...
        X