Announcement

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

  • How to modify value labels based on certain words already present in value labels

    Hello everyone,
    I have a set of categorical variables which have certain value labels attached to their value. I want to change (using loop) the value labels if these labels contain certain words. For example,

    Var1 has three values 1, 2, 3 and the respective value labels are "Bottle Large Red", "Bottle Small Black", "Bottle No data"

    I want to change all the value labels to "The bottle is large and red" if the value label contains words "Red" & "Large"; to "The bottle is small and black" if it contains words "Black" & "Small". No change if the value label does not contain all the that words I specify.

    I hope I am clear in asking my question. Kindly advise how can I do this.

    Thanks.
    Amit

  • #2
    Try this:
    Code:
    clear*
    
    //    CREATE A DEMONSTRATION TOY DATA SET
    label define example    1    "Bottle Large Red"    ///
                            2    "Bottle Small Black"    ///
                            3    "Bottle No data"
                            
    set obs 10
    set seed 1234
    gen var1:example = runiformint(1, 3)
    
    label list example
    
    //    HERE'S THE CODE
    levelsof var1, local(levels)
    local lblname: val label var1
    foreach l of local levels {
        local vlbl: label `lblname' `l'
        if strpos(`"`vlbl'"', "Red") & strpos(`"`vlbl'"', "Large") {
            label define `lblname' `l' "The bottle is large and red", modify
        }
        if strpos(`"`vlbl'"', "Black") & strpos(`"`vlbl'"', "Small") {
            label define `lblname' `l' "The bottle is small and black", modify
        }
    }
    
    label list example
    There is a flaw in this code. If there is a value in the value label that does not actually occur as a value of var1 in the data, then it will not be dealt with by this code. Of course, the value label assigned to an uninstantiated level of a variable is usually not a problem. There is another approach to this problem that gets around this, but it is considerably more complicated, so unless there is some real reason why this limitation would really be a problem in your situation, I would consider the above code to be an acceptable solution.

    Comment


    • #3
      Here are three ways of doing this with elabel (SSC).

      1. All in one (complex) call

      Code:
      clear*
      
      //    CREATE A DEMONSTRATION TOY DATA SET
      label define example    1    "Bottle Large Red"    ///
                              2    "Bottle Small Black"    ///
                              3    "Bottle No data"
      
      elabel define example                                 ///
          (= #)                                             ///
          (= cond(                                          ///
             (strpos(@, "Large")&strpos(@, "Red")),         ///
              "The bottle is large and red",                ///
              cond((strpos(@, "Small")&strpos(@, "Black")), ///
              "The bottle is small and black", @))) , modify
      
      label list example
      2. Step-by-step approach, obtaining the respective subset of integer values from value labels

      Code:
      clear*
      
      //    CREATE A DEMONSTRATION TOY DATA SET
      label define example    1    "Bottle Large Red"    ///
                              2    "Bottle Small Black"    ///
                              3    "Bottle No data"
      
      elabel list example if strpos(@, "Large") & strpos(@, "Red")
      elabel define example (`r(values)') ("The bottle is large and red") , modify
      
      elabel list example if strpos(@, "Small") & strpos(@, "Black")
      elabel define example (`r(values)') ("The bottle is small and black") , modify
      
      label list example
      3. Fix the "flaw" in Clyde's code, using elabel in place of levelsof

      Code:
      clear*
      
      //    CREATE A DEMONSTRATION TOY DATA SET
      label define example    1    "Bottle Large Red"    ///
                              2    "Bottle Small Black"    ///
                              3    "Bottle No data"
                              
      set obs 10
      set seed 1234
      gen var1:example = runiformint(1, 3)
      
      label list example
      
      //    HERE'S THE CODE [ slightly modified ]
      elabel list (var1)        // <- replaces levelsof
      local levels `r(values)'  // <- replaces levelsof
      return list               // <- just to show what else is there
      local lblname: val label var1
      foreach l of local levels {
          local vlbl: label `lblname' `l'
          if strpos(`"`vlbl'"', "Red") & strpos(`"`vlbl'"', "Large") {
              label define `lblname' `l' "The bottle is large and red", modify
          }
          if strpos(`"`vlbl'"', "Black") & strpos(`"`vlbl'"', "Small") {
              label define `lblname' `l' "The bottle is small and black", modify
          }
      }
      
      label list example
      Best
      Daniel
      Last edited by daniel klein; 26 Nov 2018, 00:19.

      Comment


      • #4
        Thank you Clyde and Daniel. Much appreciate the quick help from you.

        Best
        Amit

        Comment


        • #5
          Code:
          clear*
          
          //    CREATE A DEMONSTRATION TOY DATA SET
          label define example    1    "Bottle Large Red"    ///
                                  2    "Bottle Small Black"    ///
                                  3    "Bottle No data"
                                  
          set obs 10
          set seed 1234
          gen var1:example = runiformint(1, 3)
          
          
          // Yet another way of achieving this task
          label dir
          
          mata
          
          names = tokens(st_global("r(names)"))
          values = .
          text = ""
          for (i=1 ; i<=cols(names) ; i++ ) {
              st_vlload(names[i],values, text)
              for (j = 1 ; j <= rows(text) ; j++ ) {
                  if ( strpos(text[j], ("Large")) & strpos(text[j],("Red")) ) {
                      text[j] =  "The bottle is large and red"
                  }
                  if ( strpos(text[j], ("Small")) & strpos(text[j],("Black")) ) {
                      text[j] =  "The bottle is small and black"
                  }
              }
              st_vlmodify(names[i], values, text)
          }
          
          end
          
          label list
          ---------------------------------
          Maarten L. Buis
          University of Konstanz
          Department of history and sociology
          box 40
          78457 Konstanz
          Germany
          http://www.maartenbuis.nl
          ---------------------------------

          Comment


          • #6
            Thanks Maarten!
            Best Amit

            Comment

            Working...
            X