Announcement

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

  • Failing to use local macro joined with string to reference variable



    I am new-ish to STATA . I have a variable called wk1g12 and I am simply trying to store a 1 in it if certain criteria are met.

    The problem is when I try to reference it with "`t'g12"[`m'] = 1 it fails. The parts of this string I am forming to reference an actual variable are `t' = "wk1" and "g12".

    I thought combining these to form the string "wk1g12" would allow me to reference the variable with the same name.

    However, I get errors like "wk1g12 is not a valid command name" . I have attempted all sorts of different versions of this but none work.

    Any pointers on how I can reference the variable correctly by buidling a string of the same name... or saying this is not possible... would help a lot... or any pointers how I could reference it in the loops I have formed!

    Thanks for any help!


    Code:
    foreach t of local time_nodups {
        forvalues m=1/`=_N' {
            
            * to track whether this person has +1 to a given time point (t) yet
            local count = 0
            
            * iterate over all variables
            foreach var of varlist _all { 
                
                * if this variable refers to the correct timepoint (t)
                if(substr("`var'", -3, 3) == "`t'") { 
                
                    * and if not counted yet for this timepoint(t)
                    if(`count' == 0) {
                        
                        * and if the value matches 1 or 2
                        if(`var'[`m'] == 1 | `var'[`m'] == 2 ) {
                            
                            * to exit for this person
                            local count = 1
                            
                            * now when i create a 'string' to 'get' the name of a variable...
                            * and store a value in it.. it fails with "wk1g12 is not a valid command name"
                            
                            "`t'g12"[`m'] = 1
                    
                            
                        }
                    }
                }
            }
        }
    }

  • #2
    Well, your local macro t is the iterator of a -foreach- loop that ranges over the values of local macro time_nodups. But you don't appear to have defined that local macro. Rather, you don't show how it is defined. It must have been defined somewhere, else it would be empty and the loop would never execute at all, let alone give you an error message. But since you don't show how it's defined, it's a potential, and the most obvious, source of a problem.

    All of that said, I can't tell exactly what this code is supposed to do. But it looks like a very convoluted approach to doing something that probably can be done in just a couple of lines using -by- and -gen- or -egen- with appropriate functions. If you can state your purpose in clear terms, and provide example data (using the dataex command), probably we can eliminate your problem by just coming up with a simpler and more efficient way to do it.

    If you are running version 17, 16 or a fully updated version 15.1 or 14.2, -dataex- is already part of your official Stata installation. If not, run -ssc install dataex- to get it. Either way, run -help dataex- to read the simple instructions for using it. -dataex- will save you time; it is easier and quicker than typing out tables. It includes complete information about aspects of the data that are often critical to answering your question but cannot be seen from tabular displays or screenshots. It also makes it possible for those who want to help you to create a faithful representation of your example to try out their code, which in turn makes it more likely that their answer will actually work in your data.

    When asking for help with code, always show example data. When showing example data, always use -dataex-.

    Comment


    • #3
      Thanks for the reply Clyde. If it helps, the local macro time_nodups is created as such:

      local time_nodups wk1 wk2 wk3 wk4 wk5 wk6 nt1 nt2 nt5 nt4

      The purpose of the code overall is to eventually be able to provide the number of patients experiencing grades 1-5 of toxicties to a drug (see excerpt below), where the toxicities are measured at weeks 1-6 and a number of other time points. Thus in this figure here is how week 1 needs to look (the other 17 time points to follow):

      Induction Week 1 Number of patients assessed
      Grade 1/2 toxicities %
      Grade 3/4 toxicities %
      Grade 5 toxicities %

      ...where the data containing the grade of issue is contained in about about 500 fields (with an example below)... with about 50 different toxicties of grade 1-5 measured across 18 time points.

      hypergly_wk1 pneumo_wk2 diarr_wk2 nausea_wk2 pneumo_wk3 diarr_wk3
      0 4 1 2 2 1 (patient 1)
      0 0 0 0 0 0
      0 0 0 0 0 0
      0 0 1 0 0 0
      0 0 0 1 0 0
      1 0 1 0 0 0 (patient 6)

      Thus, in this picture, for example, pneumonia of grade 4 was experienced at time week 2.. and diarrhea of grade 1 at week 2...etc.

      You can also see in this example, that patient 1 experienced a number of grade 1 and 2 toxicities across week 2... but for the table this should only be counted 1 time at week 2 and 3 (for example) for patient 1.

      Thus the idea was:

      Code:
      * for each time point in time_nodups (this was to eliminate 100+ fields from consideration which didn't currently have data)
      foreach t of local time_nodups {
          
           * for each patient
           forvalues m=1/`=_N' {
              
              * use count to track whether this person has already had a grade 1 or 2 respone already recorded at this timepoint
              local count = 0
              
              * then iterate over all variables like in the example (hypergly_wk1    pneumo_wk2    diarr_wk2 ...)
              foreach var of varlist _all { 
                  
                  * if this variable refers to the correct timepoint (t)... which can be gathered by extracting the last three charcters (eg., hypergly_wk1 is wk1) from each variable
                  * and if that substring (e.g. wk1) equals the current timepiont we are talkign about (like wk1, wk2, etc.)
                  if(substr("`var'", -3, 3) == "`t'") { 
                  
                      * and if this patient has not been counted yet for this timepoint(t)
                      if(`count' == 0) {
                          
                          * and if the value held in that variable for the current patient (1-6) is a grade 1 or 2 event (as shown in the data above)
                          if(`var'[`m'] == 1 | `var'[`m'] == 2 ) {
                              
                              * change count to 1 so this is only counted 1 x 
                              local count = 1
                              
                                * and record that this patient had a grade 1 or 2 event (with a 1) ... in a variable that identifes the timepoint and the grade (ie, 1 or 2).  
                            
                                ``t'"g12"'[`m'] = 1
                      
                                    * once that is all done.... save the dataset and then create the table 
                          }
                      }
                  }
              }
          }
      }

      where the code for generating the variables to store the '1' for each patient at each time point that experinces this grade of issue is:

      Code:
      * for each combination of grades
      foreach k in g12 g34 g5 {
          * for each unique time point where there is at least 1 grade 1-5 toxicity
          foreach var of local time_nodups {
                  gen `var'`k' =.
          }
      }
      Can try to post dataex later with more fake data if it would help.


      Comment


      • #4
        I see. OK, the key problem here is that you have the data in wide layout, which makes nearly everything in Stata more difficult, or even impossible. Once converted to long layout, this will reduce to a few simple lines of code.

        Can try to post dataex later with more fake data if it would help.
        Yes, it's really indispensible. Use fake id variables (just consecutive numbers 1, 2, 3,... would be fine), and if you fell you need to, you can fake the actual values for the various toxicity grades, as long as they are possible values and fairly cover the range of possible values. You only need to include a handful of patients. And, as I suspect you have a large number of different toxicity variables, there is no need to show them all. Just show something like wk1_pneumo wk1_diarr wk2_pneumo wk2_diarr nt4_pneumo nt4_diarrr nt5_pneumo nt5_diarr (and a fake id variable). I'll then get back to you with code that can be easily adapted to the full data set.

        Comment


        • #5

          Ok, very many thanks for your help. Data and observations are fake and limited in nature. Any assistance is very appreciated and can help patients in difficult circumstances. I have tried to reshape to long... but it always fails. I can't understand why this fails:

          Code:
          reshape long nausea_wk1 hypergly_wk1 pneumo_wk2 diarr_wk2 nausea_wk2 pneumo_wk3 diarr_wk3 nausea_wk3 platedec_wk3 pneumo_wk4 diarr_wk4 muco_wk4 nausea_wk4 platedec_wk4 diarr_wk5 nausea_wk6, i(obs) j(j)
          So easy in excel to transpose from rows to columns it pains me I have such issue in STATA. Any suggestion what I am doing wrong?


          Dataex is :

          Code:
          * Example generated by -dataex-. For more info, type help dataex
          clear
          input float obs byte(nausea_wk1 hypergly_wk1 pneumo_wk2 diarr_wk2 nausea_wk2 pneumo_wk3 diarr_wk3 nausea_wk3 platedec_wk3 pneumo_wk4 diarr_wk4 muco_wk4 nausea_wk4 platedec_wk4 diarr_wk5 nausea_wk6)
          1 0 0 4 1 1 4 1 1 1 4 1 1 1 1 1 0
          2 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
          3 1 4 0 0 0 2 0 0 2 0 1 0 0 0 0 2
          4 0 0 0 1 0 0 0 0 0 3 0 0 4 0 0 0
          5 0 0 0 0 1 0 0 0 0 0 5 0 0 0 0 0
          6 1 1 0 1 0 0 0 3 0 3 0 0 0 0 0 1
          end
          label values nausea_wk1 nausea1_
          label def nausea1_ 0 "0", modify
          label def nausea1_ 1 "1", modify
          label values hypergly_wk1 hypergly1_
          label def hypergly1_ 0 "0", modify
          label def hypergly1_ 1 "1", modify
          label def hypergly1_ 4 "4", modify
          label values pneumo_wk2 pneumo2_
          label def pneumo2_ 0 "0", modify
          label def pneumo2_ 4 "4", modify
          label values diarr_wk2 diarr2_
          label def diarr2_ 0 "0", modify
          label def diarr2_ 1 "1", modify
          label values nausea_wk2 nausea2_
          label def nausea2_ 0 "0", modify
          label def nausea2_ 1 "1", modify
          label values pneumo_wk3 pneumo3_
          label def pneumo3_ 0 "0", modify
          label def pneumo3_ 2 "2", modify
          label def pneumo3_ 4 "4", modify
          label values diarr_wk3 diarr3_
          label def diarr3_ 0 "0", modify
          label def diarr3_ 1 "1", modify
          label values nausea_wk3 nausea3_
          label def nausea3_ 0 "0", modify
          label def nausea3_ 1 "1", modify
          label def nausea3_ 3 "3", modify
          label values platedec_wk3 platedec3_
          label def platedec3_ 0 "0", modify
          label def platedec3_ 1 "1", modify
          label def platedec3_ 2 "2", modify
          label values pneumo_wk4 pneumo4_
          label def pneumo4_ 0 "0", modify
          label def pneumo4_ 3 "3", modify
          label def pneumo4_ 4 "4", modify
          label values diarr_wk4 diarr4_
          label def diarr4_ 0 "0", modify
          label def diarr4_ 1 "1", modify
          label def diarr4_ 5 "5", modify
          label values muco_wk4 muco4_
          label def muco4_ 0 "0", modify
          label def muco4_ 1 "1", modify
          label values nausea_wk4 nausea4_
          label def nausea4_ 0 "0", modify
          label def nausea4_ 1 "1", modify
          label def nausea4_ 4 "4", modify
          label values platedec_wk4 platedec4_
          label def platedec4_ 0 "0", modify
          label def platedec4_ 1 "1", modify
          label values diarr_wk5 diarr5_
          label def diarr5_ 0 "0", modify
          label def diarr5_ 1 "1", modify
          label values nausea_wk6 nausea6_
          label def nausea6_ 0 "0", modify
          label def nausea6_ 1 "1", modify
          label def nausea6_ 2 "2", modify

          Comment


          • #6
            Code:
            reshape long nausea hypergly pneumo diarr platedec muco, i(obs) j(when) string
            replace when = subinstr(when, "_", "", .)
            
            forvalues i = 1/5 {
                egen had_grade_`i' = anymatch(nausea-muco), values(`i')
                replace had_grade_`i' = 100 * had_grade_`i'
                
            }
            
            collapse (mean) had_grade_*, by(when)
            it pains me I have such issue in STATA. Any suggestion what I am doing wrong?
            See in the above the bold-faced -string- option that was missing from your code.

            I am a little unclear about your intended final results. The results created in the code above gives, for each of the five grade levels, the percentage of patients who experienced one or more toxicities at that grade in that time period. If that's not what you wanted and want help modifying the code to your needs, please post back with a clearer explanation.

            Comment


            • #7
              Wow....that is amazing! Thanks so much Clyde. That accomplishes pretty much exactly what I need. I will never write stata code the same after this lesson. All that's left now is make it pretty with putdocx to format the output into a tablle in word.

              Comment

              Working...
              X