Announcement

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

  • Add Value Label to Existing Value Label Containers via Loop

    I have a fairly simple problem: All variables of my dataset have value labels (lblname1, lblname2, ..., lblname10.000). All values are labeled, except the missing code ".z". I want the missing code ".z" to have the label "label for .z" for all variables while keeping the existing value labels.

    I can do this via:

    Code:
    label define lblname1 .z "label for .z", add
    Yet, I would have to do this for lblname1 to lblname10.000.

    Instead of typing the above line 10.000 times, I tried to loop over the different label containers:

    Code:
    qui label list
    foreach i in `r(names)'{
     label define `i' .z "label for .z", add
    }
    I don't get an error message, but the code doesn't seem to do anything.

    My next try was like that:

    Code:
    label dir // get all value label container names
    global lblnames "lblname1 lblname2 ... lblname10.000" //
    foreach i of global lblnames {
     lab def `i' .z "label for .z", add
    }
    This results in the error message: "invalid attempt to modify label"

    What am I doing wrong?

    Thank you very much in advance.

    Andreas

  • #2
    -label list- does not return any `r(names)', so your loop with that does nothing.

    Code:
    qui label dir
    foreach i in `r(names)'{
     label define `i' .z "label for .z", add
    }
    works for me.

    Comment


    • #3
      Originally posted by Andreas Fabian Fischer View Post
      This results in the error message: "invalid attempt to modify label"

      What am I doing wrong?
      I suppose the return code is r(180). The problem is that at least one value label already defines a label for value .z. Option add allows you to add new values to value labels, i.e., values for which no label (text) has been defined. You could use option modify to modify existing labels:

      Code:
      . clear
      
      . label define foo .z "label for .z"
      
      . label define foo .z "label for .z" , add
      invalid attempt to modify label
      r(180);
      
      . label define foo .z "label for .z" , modify
      
      . label list
      foo:
                .z label for .z

      See how my first attempt to "add" a value label for .z results in error. It is because .z already has a label. The second attempt appears to work. I say it appears to work because there is a huge problem that I see. Suppose the following situation:

      Code:
      . clear
      
      . label define foo .z "some other label"
      
      . label define foo .z "label for .z" , modify
      
      . label list
      foo:
                .z label for .z

      Now the original label for .z is gone. Why is this a problem? Because you have not changed any of the variables that use value label foo. If .z in those variables represents "some other label" then I would now be misled to believe it represents "label for .z". Here is the same example with more descriptive value labels:

      Code:
      . clear
      
      . input condition
      
           condition
        1. 1
        2. end
      
      .
      . label define condition 1 "headache"
      
      . label values condition condition
      
      .
      . tabulate condition
      
        condition |      Freq.     Percent        Cum.
      ------------+-----------------------------------
         headache |          1      100.00      100.00
      ------------+-----------------------------------
            Total |          1      100.00
      
      .
      . label define condition 1 "brain tumor" , modify
      
      .
      . tabulate condition
      
        condition |      Freq.     Percent        Cum.
      ------------+-----------------------------------
      brain tumor |          1      100.00      100.00
      ------------+-----------------------------------
            Total |          1      100.00

      See the problem better now?

      You probably do not want to change value labels in that way, especially in a loop without even looking at the value labels. Thus, I recommend not using option modify.

      elabel (SJ, SSC, or GitHub) has an undocumented option, append, for these situations.

      Code:
      . clear
      
      . label define no_label_for_z 42 "foo"
      
      . label define same_label_for_z .z "label for .z"
      
      . elabel define * .z "label for .z" , add append
       
      . label list
      no_label_for_z:
                42 foo
                .z label for .z
      same_label_for_z:
                .z label for .z
      The option lets you add a label for .z if it does not exist and leaves it unchanged if it does. Moreover, if there was a different label for .z, the option still results in error:

      Code:
      . clear
      
      . label define no_label_for_z 42 "foo"
      
      . label define other_label_for_z .z "some other label"
      
      . elabel define * .z "label for .z" , add append
      invalid attempt to modify label
      r(180);

      I argue that this is what you want because you have not anticipated it and you want to take a closer look at the underlying problem.


      Sorry for the somewhat lengthy post but I believe this potential problem is often overlooked.
      Last edited by daniel klein; 15 Jan 2024, 01:55.

      Comment


      • #4
        @Clyde and @daniel: Thank you both very much for your responses and sorry that mine is so late and short. I will give a proper response soon; time is a scarce commodity for me right now.

        Comment

        Working...
        X