Announcement

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

  • Excluding specific combinations of variables from a foreach variable loop with 2 or more varlists

    Hi all

    I have 2 lists of variables (i.e. varlist1 and varlist2) and I would like to use a command that combines both varlists, such as scatter (example below).

    Example:
    Code:
    sysuse auto, clear
    
    foreach var1 of varlist price headroom trunk{ 
    foreach var2 of varlist weight length turn{
    
    scatter `var1' `var2'
    
    }
    }
    I would use a foreach variable loop inside another foreach variable loop and this would work perfectly if I wanted all possible combinations of varlist1 with varlist2, but I would like to exclude certain combinations, such as price and turn for example. Does anyone know of a more efficient way to do this without having to exclude this combination manually?

    Thank you
    Filipe

  • #2
    The problem is clear but imprecise. How are the "certain combinations" defined? Beyond a certain point, it would be simpler to list the pairs you did want than the pairs you did not want.

    Comment


    • #3
      Thank you. In the problem I am working on at the moment the pairs to exclude can either be arbitrary (based on previous knowledge) or sometimes they based on logic. I wonder if there is a way I could use a matrix to define which pairs should the loop apply to, or if I could apply a sort of conditional to the loop?

      Using the example above, something like this (although I know this particular suggestion doesn't work) to exclude pairs price/turn and trunk/lenght:

      Code:
      sysuse auto, clear
      
      foreach var1 of varlist price headroom trunk{
      foreach var2 of varlist weight length turn{
      if (`var1'!= price & `var2'!=turn) | (`var1'!= trunk & `var2'!=lenght)
      
      scatter `var1' `var2'
      }}

      Comment


      • #4
        You could write a long test excluding pairs you don't want, but even with two exclusions the code you have is messy and hard to debug.

        Note that you are testing variable names, not their values, and that your innermost operator needs be & not | (otherwise trunk and length is an acceptable combination, because trunk is not price and length is not turn).

        This works and is I think easier to extend ad hoc.

        Code:
        sysuse auto, clear
        
        local g = 1
        foreach var1 in price headroom trunk {
            foreach var2 in weight length turn {
                if "`var1'" == "price" & "`var2'" == "turn" continue
                if "`var1'" == "trunk" & "`var2'" == "length" continue  
                scatter `var1' `var2', name(G`g')
                local ++g
            }
        }
        It is usually a lot easier to get all the graphs and ignore those you want!
        Last edited by Nick Cox; 09 Apr 2019, 03:58.

        Comment


        • #5
          Thank very much Nick. This is very helpful. I am not really generating graphs but this solves the problem.

          As an extension, sometimes this could be useful if I could instead of typing all the variable combinations I want to exclude, I could select groups of variables. For example exclude all combinations where the name of the first variable in the combination ends in price and the second variable is turn. Again, I know the example below doesn't work but I think it exemplifies the logic:

          Code:
          if "`var1'" == "*price" & "`var2'" == "turn" continue

          I understand that I can attain the same results with the code below, but I am trying to figure out if this can be abbreviated in case there is a long list of *price variables for example.

          Code:
          if inlist("`var1'", "first_price", "second_price", ~"third_price") & "`var2'" == "turn" continue

          Comment


          • #6
            Code:
            help extended functions
            tells you about list manipulation, e.g. how to get one list MINUS another.

            Comment

            Working...
            X