Announcement

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

  • Using foreach loop for value labels

    Hi,

    I am trying to use a loop to change how three values are labeled across a few (3) variables. I have played around with variations of the following, but I keep receiving "invalid snytax." Would appreciate any thoughts on how to label the numeric values with the textual description.

    local vars "q13_1_s q13_2_s q13_3_s"
    foreach var of `vars' {
    label define `vars' 1 "Worse", modify
    label define `vars' 2 "About the same", modify
    label define `vars' 3 "Better", modify
    }
    Thank you so much!

    Best,
    Caroline

  • #2
    The problem is in the line

    Code:
    foreach var of `vars' {
    There are actually three different ways you could correct this:

    Code:
    foreach v of local vars {
    
    foreach v of varlist `vars' {
    
    foreach v in `vars' {
    Carefully re-read the -foreach- section of the online user's manual. You will see that -foreach .- is always followed by either -in- or -of-. If followed by -of-, then -of- is, in turn, followed by a keyword such as -varlist-, -numlist-, or -local-. When -foreach ..- is followed by -in-, then no such keyword is necessary, and only the actual list of strings to be iterated over appears directly after -in-.

    Comment


    • #3
      Dear Clyde,

      Thank you very much for your prompt response! I have read more carefully the foreach help (as I should have done before) and understand my issue with that line. Thank you for pointing that out.

      Unfortunately, however, the code is still not working. I have tested it with other commands, and it seems that the error is in the line label define `vars' 1 "Worse", modify.

      Is there a different way that I am supposed to use label define within a loop?

      Many thanks,
      Caroline

      Comment


      • #4
        Caroline: It's still best to show your exact code and not make us guess what it is.

        Clyde was fixing your outer loop, but the inner statements are still wrong. Various ways to fix that:

        Code:
        local vars "q13_1_s q13_2_s q13_3_s"
        foreach v of local vars {
             label define `v' 1 "Worse", modify
             label define `v' 2 "About the same", modify
             label define `v' 3 "Better", modify
        }

        The local macro name used inside the loop should correspond to that defined in the loop statement.

        Not the question, but this could also be rewritten:


        Code:
        local vars "q13_1_s q13_2_s q13_3_s"
        foreach v of local vars {
             label define `v' 1 "Worse" 2 "About the same" 3 "Better", modify
             label val `v' `v' 
        }
        The last command may be redundant. We can't tell given lack of full disclosure.
        Last edited by Nick Cox; 10 Jan 2017, 11:16.

        Comment


        • #5
          Thank you very much, Nick. This makes sense to me now, and the loop is working!

          I apologize for not showing the exact code. I will do so in the future, as I just joined here yesterday.

          Many thanks!

          Comment


          • #6
            Hi I am using levelsof command. I have value labels attached to a variable, and using that variable in my twoway command. NIC1 (later renamed to sector is my variable with value labels. ) I make a different twoway graph for every value of the variable sector.

            My code is as follows:

            label define NIC1Label 0 "Agriculture, Forestry and Fishing" 1 "Mining, Utilities and Construction" 2 "Manufacturing" 3 "Trade" 4 "Transport, Accomodation" ///
            5 " Info. & Communication" 6 "Finance, Insurance & Real Estate" 7 "Professional, Technical and Admin. Services" 8 "Educ & Health" ///
            9 "Arts, Recreation & Others" 10 "Diversified"
            label values NIC1 NIC1Label
            rename NIC1 sector


            levelsof sector, clean local(sector)
            foreach r of local sector {

            twoway (connected percent_sector varna if sector == `r' , lwidth(vvvthin)) , ytitle(Percentage of firms) ytitle(, color(red)) xtitle(Varnas) xtitle(, color(red)) ///
            xscale(range(1 14)) xlabel(1(1)14, labels labsize(small) labgap(medsmall) valuelabel alternate ticks) ///
            title(Percentage Composition by Varna for Sector_`r') subtitle((Sectors over all years)) legend(off) xsize(20) ysize(10) ///
            saving(sector_`r')
            }


            What I would want is, in the title() and saving() options, the value label to appear rather than the number itself. Can someone help?

            Comment


            • #7
              Hi Priyoma,
              for doing that you have to extract the value label associated to each value `r' within the loop: see -help extended_fcn- for extracting the attribute you need


              Code:
              levelsof sector, clean local(sector)
              foreach r of local sector {
              
                  local vl : label (sector) `r'
              
                  twoway (connected percent_sector varna if sector == `r',///
                      lwidth(vvvthin)) , ytitle(Percentage of firms) ///
                      ytitle(, color(red)) xtitle(Varnas) xtitle(, color(red)) ///
                      xscale(range(1 14)) xlabel(1(1)14, labels labsize(small) ///
                      labgap(medsmall) valuelabel alternate ticks) ///
                      title("Percentage Composition by Varna for Sector `vl'") ///
                      subtitle((Sectors over all years)) legend(off) xsize(20) ///
                      ysize(10) saving("sector `vl'")
              }
              Above the value labels are stored in the local vl

              Raffaele

              Comment


              • #8
                Hi,
                I'm trying to add some labels to the existing value labels in a dataset. So far, I've tried the following code:

                Code:
                foreach var of varlist R0000100-HHNETWORTH_AGE35 {
                label define `var' .a "Refusal" .b  "Don't Know" .c "Invalid Skip" .d "Valid Skip" .e "Non-Interview", add
                }
                However, all I've achieved is to add a large set of new value labels with the given code. Although I can manually change each value label in the dataset, that would be a rather tedious process. How can I use the foreach command for the existing value labels in the dataset?

                Thanks in advance.

                Comment


                • #9
                  From your description I assume that your dataset already contain value lables, and you want to change all these. label dir gives you a list of all value labels in your dataset, and returns them in r(names). So we can loop over those, and change those:

                  Code:
                  label dir
                  foreach lab in `r(names)' {
                      label define `lab' .a "Refusal" .b  "Don't Know" .c "Invalid Skip" .d "Valid Skip" .e "Non-Interview", add
                  }
                  ---------------------------------
                  Maarten L. Buis
                  University of Konstanz
                  Department of history and sociology
                  box 40
                  78457 Konstanz
                  Germany
                  http://www.maartenbuis.nl
                  ---------------------------------

                  Comment


                  • #10
                    This is on of the tasks that elabel (SSC) makes fairly simple.

                    Code:
                    elabel define * .a "Refusal" .b "Don't Know" .c "Invalid Skip" .d "Valid Skip" .e "Non-Interview", add
                    Best
                    Daniel

                    Comment


                    • #11
                      Thank you so much Daniel and Maarten for the prompt replies.
                      Both worked well.
                      Last edited by Salman Mallick; 23 Mar 2020, 04:08.

                      Comment


                      • #12
                        Hi,
                        I am trying to use a loop to change how 4 values are labeled across 9 variables. My code is as follows:

                        Code:
                        local vars "MF901A_MH" "MF901B_MH" "MF901C_MH" ///
                         "MF901D_MH" "MF901E_MH" "MF901F_MH" "MF901G_MH" ///
                         "MF901H_MH" "MF901I_MH"
                        foreach v of local vars {
                             label define `v' 0 "Not at all", modify
                             label define `v' 1 "Some days", modify
                             label define `v' 2 "Majority of the days", modify
                             label define `v' 3 "Nearly every day", modify
                        }
                        I keep receiving "invalid syntax." Can somebody help?

                        Comment


                        • #13
                          Get rid of all those quotes in your definition of -local vars-. Only use quotes in defining a local macro if they are essential to designate a sequence of characters with interior spaces as a single "word." And always avoid them at the beginning or end.

                          That said, there is probably no need for this loop in the first place. You can just define a single label and apply it to all of the variables
                          Code:
                           label define mylabel 0 "Not at all" ///
                               1 "Some days" ///
                               2 "Majority of the days" ///
                               3 "Nearly every day"
                           
                           label values MF901A_MH MF901B_MH MF901C_MH ///
                           MF901D_MH MF901E_MH MF901F_MH MF901G_MH ///
                           MF901H_MH MF901I_MH  mylabel
                          I'm making the assumption here that the MF901*_MH expressions are all variables in your data set and that your intent is to label them all in the same way.
                          Last edited by Clyde Schechter; 05 Jan 2023, 15:06.

                          Comment


                          • #14
                            Thank you so much Clyde. Your assumption were right.

                            Comment

                            Working...
                            X