Announcement

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

  • For Value Loop

    Hi,

    I want to do a "for-value-loop" to create a variable that shows the Gini-Coefficients (made by ginidesc) for the different features of different regional variables. In the following i first tried it for the regional variable with the smallest number of features "REGION" by hand and then with the for value loop, but the order of the values is wrong and i do not know why. Then, i try to do the same thing for the regional variable "CITY" which has more features and it does not work at all. It would be great if someone could help me! Thank you!

    ginidesc INCOME, bygroup(REGION)
    gen gini_REGION=0.568 if REGION==1
    replace gini_REGION=0.579 if REGION==2
    replace gini_REGION=0.529 if REGION==3
    *create the variable that we want:
    gen gini_regiontry = .
    *create local with that gives us the number of the provinces
    ginidesc allincome, bygroup(REGION) gkmat(ginisregion)
    distinct REGION
    local region_list = r(ndistinct)
    disp(`region_list')
    ** Loop through each province **
    local i = 1
    forvalues i = 1(1)`region_list' {
    disp(`i')
    **Extract the Gini coefficient from the matrix**
    local gini_value = ginisregion[`i',2]
    disp(`gini_value')
    **Assign the Gini coefficient to the corresponding province**
    replace gini_regiontry = `gini_value' if REGION == `i'

    local ++i
    }
    local region_list = r(ndistinct)
    disp(`region_list')
    ** Loop through each province **
    local i = 1
    forvalues i = 1(1)`region_list' {
    disp(`i')
    **Extract the Gini coefficient from the matrix**
    local gini_value = ginisregion[`i',2]
    disp(`gini_value')
    **Assign the Gini coefficient to the corresponding province**
    replace gini_city = `gini_value' if PARROQUIA7 == `i'

    local ++i
    }



    ***try for another region: city***

    gen gini_city=.
    local region_list = r(ndistinct)
    disp(`region_list')
    ** Loop through each province **
    local i = 1
    forvalues i = 1(1)`region_list' {
    disp(`i')
    **Extract the Gini coefficient from the matrix**
    local gini_value = ginisregion[`i',2]
    disp(`gini_value')
    **Assign the Gini coefficient to the corresponding province**
    replace gini_city = `gini_value' if PARROQUIA7 == `i'

    local ++i
    }


  • #2
    It's difficult to help you on this since you don't provide example data, nor do you give a specific error message or description of where things are going wrong, but there does seem to be a clear issue here. Your loops have this form:

    Code:
    local i = 1
    forvalues i = 1(1)`region_list' {
        local ++i
    }
    The first line should have no effect because the local i is defined by the for loop. You also increment i in the for loop which is redundant. The for loop will increment i on your behalf. Here is the correct form of a forvalues loop:

    Code:
    local region_list = 10
    forvalues i = 1(1)`region_list' {
        display "`i'"
    }
    Alternatively, since you increment by 1 you can just write it with a slightly simpler syntax like this:

    Code:
    local region_list = 10
    forvalues i = 1/`region_list' {
        display "`i'"
    }
    If you want to increment by 2 the right way to do it is like this:

    Code:
    local region_list = 10
    forvalues i = 1(2)`region_list' {
        display "`i'"
    }

    Comment


    • #3
      By the way, welcome to the forum! Please read the FAQ at the top for some common advice about how to write posts that elicit good answers.

      Comment


      • #4
        Let me add a little to Daniel Schaefer's excellent advice, as I believe you have an additional problem with the loop over cities.
        Code:
        gen gini_city=.
        local region_list = r(ndistinct)
        is incorrect. The -gen- command does not leave -r(ndistinct)- behind. In fact, it doesn't leave anything at all in -r()-. So r(ndistinct) evaluates to missing value. Your forvalues loop then parses as -forvalues i = 1(1) {-, which is a syntax error. You need to precede that -local region_list = r(ndistinct)- command with something that leaves behind -r(ndistinct)-. The -distinct- command (from SSC) does that, which is why your first try with regions instead of cities runs. I think you need another -distinct- command here.

        Comment


        • #5
          Just a detailed footnote on #4. The community-contributed command distinct has been updated various times. Some Stata output, edited slightly to cut irrelevant detail, explains.

          In short, Gary Longton and I last updated distinct in the Stata Journal in 2023. The version on SSC isn't up-to-date, yet that version would certainly leave r(ndistinct) in its wake. for the last variable examined, typically the last (= first) variable of one variable supplied.

          Code:
          . search distinct,sj
          
          Search of official help files, FAQs, Examples, and Stata Journals
          
          SJ-23-4 dm0042_5  . . . . . . . . . . . . . . . . Software update for distinct
                  (help distinct, distinctgen if installed)  N. J. Cox and G. M. Longton
                  Q4/23   SJ 23(4):1096
                  comments out (and thus removes) a call to clear Mata at the
                  close of work, which was frustrating some other projects
                  also using Mata
          
          SJ-23-2 dm0042_4  . . . . . . . . . . . . . . . . Software update for distinct
                  (help distinct, distinctgen if installed)  N. J. Cox and G. M. Longton
                  Q2/23   SJ 23(2):595--596
                  most important change is addition of distinctgen command
          
          SJ-20-4 dm0042_3  . . . . . . . . . . . . . . . . Software update for distinct
                  (help distinct if installed)  . . . . . .  N. J. Cox and G. M. Longton
                  Q4/20   SJ 20(4):1028--1030
                  sort() option has been added
          
          SJ-15-3 dm0042_2  . . . . . . . . . . . . . . . . Software update for distinct
                  (help distinct if installed)  . . . . . .  N. J. Cox and G. M. Longton
                  Q3/15   SJ 15(3):899
                  improved table format and display of large numbers of
                  observations
          
          SJ-12-2 dm0042_1  . . . . . . . . . . . . . . . . Software update for distinct
                  (help distinct if installed)  . . . . . .  N. J. Cox and G. M. Longton
                  Q2/12   SJ 12(2):352
                  options added to restrict output to variables with a minimum
                  or maximum of distinct values
          
          SJ-8-4  dm0042  . . . . . . . . . . . .  Speaking Stata: Distinct observations
                  (help distinct if installed)  . . . . . .  N. J. Cox and G. M. Longton
                  Q4/08   SJ 8(4):557--568
                  shows how to answer questions about distinct observations
                  from first principles; provides a convenience command
          
          (end of search)
          
          . ssc type distinct.ado
          *! 1.2.1 NJC 1 March 2012         
          *! 1.2.0 NJC 15 September 2008
          * 1.1.1 GML NJC 26 February 2002
          * 1.1.0 GML NJC 25 February 2002
          * 1.0.0 21 November 2001
          program distinct, rclass sortpreserve byable(recall)
                  version 8.0
                  syntax [varlist] [if] [in] [, MISSing Abbrev(int -1) Joint ///
                  MINimum(int 0) MAXimum(int -1) ]
          
                  if `maximum' == -1 local maximum . 
          
                  if `minimum' > `maximum' { 
                          local swap `minimum' 
                          local minimum `maximum' 
                          local maximum `swap' 
                          di as txt "min(`maximum') max(`minimum') interpreted as min(`minimum') max(`maximum')" 
                  }
          
                  if "`joint'" != "" { 
                          di 
                          di in text "        Observations" 
                          di in text "      total   distinct"
          
                          if "`missing'" != "" marksample touse, novarlist 
                          else marksample touse, strok  
                          tempvar vals 
                          bysort `touse' `varlist': gen byte `vals' = (_n == 1) * `touse'
                          su `vals' if `touse', meanonly 
          
                          if r(sum) >= `minimum' & r(sum) <= `maximum' { 
                                  di as res %11.0g r(N) "  " %9.0g r(sum)  
                          }
                  } 
          
                  else { 
                          if `abbrev' == -1 { 
                                  foreach v of local varlist { 
                                          local abbrev = max(`abbrev', length("`v'")) 
                                  }
                          }
          
                          local abbrev = max(`abbrev', 5) 
                          local abbp2 = `abbrev' + 2 
                          local abbp3 = `abbrev' + 3 
          
                          di
                          di as txt _col(`abbp3') "{c |}        Observations"
                          di as txt _col(`abbp3') "{c |}      total   distinct"
                          di as txt "{hline `abbp2'}{c +}{hline 22}"
          
                          foreach v of local varlist {
                                  tempvar touse vals
                                  mark `touse' `if' `in'
                                  // markout separately for each variable in varlist
                                  if "`missing'" == "" markout `touse' `v', strok 
                                  bys `touse' `v' : gen byte `vals' = (_n == 1) * `touse'
                                  su `vals' if `touse', meanonly
                                  if r(sum) >= `minimum' & r(sum) <= `maximum' { 
                                          di " " as txt %`abbrev's abbrev("`v'", `abbrev') ///
                                          " {c |}  " as res %9.0g r(N) "  " %9.0g r(sum)
                                  } 
                                  drop `touse' `vals'
                          } 
                  }
          
                  return scalar N = r(N)
                  return scalar ndistinct = r(sum)
          end
          
          .

          Comment


          • #6
            Thank you very much for your answers! I'm still struggling a little to find the correct way do carry it out. I attached a file at a point where i want to do the the for-value-loop. Maybe you can help me even better now?

            Thanks!
            Attached Files

            Comment


            • #7
              Please, before posting read the complete Stata Forum's FAQ, it surely will pay off! Especially #12 to better understand why you should not expect that anyone will open data files you are attaching and what alternatives to sending data files exist.

              Comment


              • #8
                Here are some modifications for your code.

                A few things that we do:
                • we can get the number of regions / cities just from the number of rows of the matrix returned by ginidesc
                • ginidesc does not sort the rows of the matrix in ascending order of the regions / cities; So we will use an index for the row number, but extract the region / city number from the matrix
                • ginidesc needs the group variable to be numeric not string. Your city variable PARROQUIA is string, so we will first convert that to numeric.
                So here is what I would do:
                Code:
                *create the variable that we want:
                gen gini_regiontry = .
                *create local with that gives us the number of the provinces
                ginidesc allincome, bygroup(REGION) gkmat(ginisregion)
                local region_list = rowsof(ginisregion)
                
                ** Loop through each province **
                forval i = 1/`region_list' {
                    **Extract the Gini coefficient from the matrix**
                    local gini_value = ginisregion[`i', 2]
                    ** Extract the region number from the matrix**
                    local region_value = ginisregion[`i', 1]
                    dis "Region: `region_value'; Gini: `gini_value'"
                    **Assign the Gini coefficient to the corresponding province**
                    replace gini_regiontry = `gini_value' if REGION == `region_value'
                }
                
                destring PARROQUIA, gen(PARROQUIA_num)
                ginidesc allincome, by(PARROQUIA_num) gkmat(giniscity)
                local city_list = rowsof(giniscity)
                gen gini_city = .
                ** Loop through each city **
                forval i = 1/`city_list' {
                    **Extract the Gini coefficient from the matrix **
                    local gini_value = giniscity[`i', 2]
                    ** Extract the city number from the matrix **
                    local city_value = giniscity[`i', 1]
                    dis "City: `city_value'; Gini: `gini_value'"
                    **Assign the Gini coefficient to the corresponding city**
                    replace gini_city = `gini_value' if PARROQUIA_num == `city_value'
                }
                Lastly, for others trying to follow this: ginidesc is a community-contributed command, available via SSC.
                Last edited by Hemanshu Kumar; 05 May 2025, 02:11.

                Comment

                Working...
                X