Announcement

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

  • how to associate two lists in a foreach

    I have files named arq1991_1996 (for years 1991 and 1996), arq1996_2000 (for years 1996 and 2000) and arq2000_2007 (for years 2000 and 2007). In each of those files I have variables for the two years considered in their respective names. For example, for the file arq1991_1996 I have variables such as nbed1991 and nbed1996 (number of beds in 1991 and 1996), ndoc1991 and ndoc1996 (number of doctor in 1991 and 1996), etc. I would like to run similar commands for all these files considering the variables for the respective two years.

    How could I do so with foreach? I would like to associate the list of substrings for files names {1991_1996, 1996_2000 and 2000_2007} to substrings of variables names {1991, 1996, 2000, 2007} where 1991_1996 should be associated to 1991 and 1996, 1996_2000 to 1996 and 2000 and 2000_2007 to 2000 and 2007.

    Thank you.

  • #2
    Here is some technique to get you started.
    Code:
    . local years 1991 1996 2000 2007
    
    . forvalues i = 1/3 {
      2.     local j = `i' + 1
      3.     local firstyear : word `i' of `years'
      4.         local lastyear  : word `j' of `years'
      5.         local filename arq`firstyear'_`lastyear'
      6.         display "`firstyear' `lastyear' `filename'"
      7.         // analysis commands here
    .         }
    1991 1996 arq1991_1996
    1996 2000 arq1996_2000
    2000 2007 arq2000_2007

    Comment


    • #3
      There are a few ways to do this. (I don't know of a quick way to zip together lists like in Python, though.) In these examples I suppose you want to create a "beds per doctor" variable for each year, or look at the change in number of beds over the period

      Code:
      * Method 1 (specific to this example): create a list of the file suffixes (1991_1996 etc.)
      *  then for each of those, convert the "_" to a space to get a list of the relevant years
      local yearsuffixes 1991_1996 1996_2000 2000_2007 
      foreach yearsuffix of local yearsuffixes {
           use arq`yearsuffix', clear
           local years = subinstr("`yearsuffix'","_"," ",.)
           // beds per doctor in each year
           foreach year of local years { // `years' will be, e.g. 1991 1996
                // so on the first iteration of the bigger loop, this smaller loop will
                // loop through those two years
                gen beds_per_doctor`year' = nbed`year'/ndoc`year'
           }
           // change in number of beds over period
           tokenize `years' 
           gen change_in_beds = nbed`2' - nbed`1'
      }
      
      * Method 2 (more general, but also more manual): create lists tied to each
      *  element of the list 1991_1996 1996_2000 2000_2007 
      local yearsuffixes 1991_1996 1996_2000 2000_2007 
      local list_1991_1996 1991 1996
      local list_1996_2000 1996 2000
      local list_2000_2007 2000 2007
      foreach yearsuffix of local yearsuffixes {
           use arq`yearsuffix', clear
           // beds per doctor in each year
           foreach year of local list_`yearsuffix' { 
                gen beds_per_doctor`year' = nbed`year'/ndoc`year'
           }
           // change in number of beds over period
           tokenize list_`yearsuffix'
           gen change_in_beds = nbed`2' - nbed`1'
      }

      Comment


      • #4
        I have yet different technique to suggest:

        Code:
        foreach arg in "1991 1996" "1996 2000" "2000 2007" {
            local first = word("`arg'", 1)
            local second = word("`arg'", 2)
            local both : subinstr local arg " " "_", all
            use arq_`both', clear
            <code in terms of those locals>
        }
        Otherwise put, there are three small bags here. Present them as such, and then look inside each bag.

        Comment


        • #5
          Thank you so much!

          Nick, I have same codes for the locals `first' and `second', so I write another foreach where you wrote
          <code in terms of those locals> However, it did not work. I got the error r(198).


          Code:
          . foreach arg in "91 96" "96 00" "00 07" {
            2.     local first = word("`arg'", 1)
            3.     local second = word("`arg'", 2)
            4.     local both : subinstr local arg " " "_", all
            5.     use compara00_07_temp`both', clear
            6.         destring *, replace
            7.         
          .         foreach i `first' `second'      {
            8.                 gen munic`i' = 100000*uf`i' + munic`i'
            9. 
          . }       
           10. }
          file compara00_07_temp91_96.dta not found
          r(601);
          
          end of do-file
          
          r(601);
          
          . do "C:\Users\Paula\AppData\Local\Temp\STD02000000.tmp"
          
          . 
          . foreach arg in "91 96" "96 00" "00 07" {
            2.     local first = word("`arg'", 1)
            3.     local second = word("`arg'", 2)
            4.     local both : subinstr local arg " " "_", all
            5.     use compara`both'_temp, clear
            6.         destring *, replace
            7.         
          .         foreach i `first' `second'      {
            8.                 gen munic`i' = 100000*uf`i' + munic`i'
            9. 
          . }       
           10. }
          uf96 has all characters numeric; replaced as byte
          munic96 has all characters numeric; replaced as long
          distr96 has all characters numeric; replaced as byte
          sdist96 has all characters numeric; replaced as byte
          setor96 has all characters numeric; replaced as int
          uf91 has all characters numeric; replaced as byte
          munic91 has all characters numeric; replaced as long
          distr91 has all characters numeric; replaced as byte
          sdist91 has all characters numeric; replaced as byte
          setor91 has all characters numeric; replaced as int
          codform has all characters numeric; replaced as int
          controle already numeric; no replace
          invalid syntax
          r(198);
          
          end of do-file
          
          r(198);
          
          .

          Comment


          • #6
            oh, sorry, I have just noticed I forgot the -in- at
            foreach i in `first' `second'

            Comment


            • #7
              You left out the required syntax in

              Code:
              foreach i in `first' `second'
              All documented: see the help for foreach

              Comment

              Working...
              X