Announcement

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

  • Defining value labels using variables in loop - how to extract the value of the nth observation of a variable within a group?

    Hi, I am trying to automate the definition of value labels using 3 variables within a dta: varname (the variable to be labelled), code (the variable value), parameter (the label). Once defined, I plan to use these to label a different dta. I struggling to automate the label definitions, I wondered if there was a way to save as a local the value of the nth observation of a specific variable within a group?

    EXAMPLE DATASET:
    Code:
    clear
    input str4 varname code str8 parameter
    var1 1 label1_1
    var1 2 label1_2
    var1 3 label1_3
    var1 4 label1_4
    var1 5 label1_5
    var1 6 label1_6
    var2 0 label2_0
    var2 1 label2_1
    end
    From this dataset I would want to save the following label lists:

    Code:
    label define var1labels 1 "label1_1" 2 "label1_2" 3 "label1_3" 4 "label1_4" 5 "label1_5" 6 "label1_6"
    label define var2labels 0 "label2_0" 2 "label2_1"
    I have an idea of how I can go about it, but it relies on me referring to the value of code and parameter that correspond to the nth observation within each group, which I'm unsure how to do. I also want to be able to extract the value of the varname variable corresponding to each group so that I can name my value label definition accordingly, allowing me to easily automate labelling later on.

    Code:
    egen grp = group(varname)
    sort grp code
    levelsof grp, local(groups)  // create local with all unique group values
    egen grp_count = count(varname), by(grp) // count obs per grp
    foreach grpnum of local groups { // loop through each vargrp
        count if grp == `grpnum'
        local grpcount = r(N)
        di "Group `grpnum'; Count: `grpcount'" // check working
        local list = "label define `grpnum'" // ideally want to extract varname value, not `grpnum'
        forval i = 1/`grpcount' {
    //      local codeval = code[`i'] // something like this?
    //      local parameterval = parameter[`i']
    //      local list = `list' + " `codeval' `parameterval'" // planning to iteratively build the label definition
    //      di "`list'"
        }
    }
    I'd be really grateful if anybody had any tips! Thank you so much in advance


  • #2
    I recommend Roger Newson's -vallabdef- command which seems to perfectly tackle your problem.

    Code:
    clear
    input str4 varname code str8 parameter
    var1 1 label1_1
    var1 2 label1_2
    var1 3 label1_3
    var1 4 label1_4
    var1 5 label1_5
    var1 6 label1_6
    var2 0 label2_0
    var2 1 label2_1
    end
    
    ssc install vallabdef
    
    vallabdef varname code parameter
    
    label list
    
    . label list
    var1:
               1 label1_1
               2 label1_2
               3 label1_3
               4 label1_4
               5 label1_5
               6 label1_6
    var2:
               0 label2_0
               1 label2_1

    Comment


    • #3
      Hmm, here is a simple if somewhat wacky idea:

      Code:
      clear
      input str4 varname code str8 parameter
      var1 1 label1_1
      var1 2 label1_2
      var1 3 label1_3
      var1 4 label1_4
      var1 5 label1_5
      var1 6 label1_6
      var2 0 label2_0
      var2 1 label2_1
      end
      
      sort varname code
      gen varlabel = " " + string(code) + " " + parameter
      gen varlabdef = ""
      replace varlabdef = cond(varname == varname[_n-1], varlabdef[_n-1] + varlabel, varlabel)
      by varname (code): replace varlabdef = cond(_n == _N, "label define " + varname + "label" + varlabdef, "")
      which then can produce:
      Code:
      . list varlabdef if !missing(varlabdef), noobs sep(0)
      
        +------------------------------------------------------------------------------------------+
        |                                                                                varlabdef |
        |------------------------------------------------------------------------------------------|
        | label define var1label 1 label1_1 2 label1_2 3 label1_3 4 label1_4 5 label1_5 6 label1_6 |
        |                                             label define var2label 0 label2_0 1 label2_1 |
        +------------------------------------------------------------------------------------------+
      
      . levelsof varlabdef, local(labdefs)
      `"label define var1label 1 label1_1 2 label1_2 3 label1_3 4 label1_4 5 label1_5 6 label1_6"' `"label define var2label 0 label2_0 1 label2_1"'
      Last edited by Hemanshu Kumar; 11 Feb 2025, 00:18.

      Comment


      • #4
        This may help as a fairly direct attack. Notice that I avoided the use of a local macro. See also https://journals.sagepub.com/doi/pdf...867X0600600313 and
        https://journals.sagepub.com/doi/pdf...867X0600600414

        Code:
        clear
        input str4 varname code str8 parameter
        var1 1 label1_1
        var1 2 label1_2
        var1 3 label1_3
        var1 4 label1_4
        var1 5 label1_5
        var1 6 label1_6
        var2 0 label2_0
        var2 1 label2_1
        end
        
        levelsof varname, local(myvars) clean
        
        gen order = _n
        
        foreach v of local myvars {
            levelsof code if varname == "`v'", local(myvals)  
            foreach c of local myvals {
                su order if varname == "`v'" & code == `c', meanonly
                label def `v' `c' "`=parameter[r(min)]'", modify
            }
        }
        
        label li
        
        label save `myvars' using mylabels.do
        
        type mylabels.do
        Resulting do-file contains

        Code:
        label define var1 1 `"label1_1"', modify
        label define var1 2 `"label1_2"', modify
        label define var1 3 `"label1_3"', modify
        label define var1 4 `"label1_4"', modify
        label define var1 5 `"label1_5"', modify
        label define var1 6 `"label1_6"', modify
        label define var2 0 `"label2_0"', modify
        label define var2 1 `"label2_1"', modify

        Comment

        Working...
        X