Announcement

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

  • Stata 18 dtable command - can I display single row for binary variables?

    I've just installed Stata 18 and have been trying out a few things with the new -dtable- command. I'm sure I'll use this command frequently in my work and especially like the ease of automating and reproducing descriptive tables. Thanks Stata!!!
    I do however have one question/wish.

    Here's my code:
    Code:
    *Reading in the low birthweight dataset available on the Stata Press website.
    use https://www.stata-press.com/data/r18/lbw,clear
    
    *Adding value label to the low birthweight and hypertension variables.
    lab def noyes 0 No 1 Yes
    lab val low ht noyes
    
    *Creating descriptive table.
    dtable age i.race i.ht, by(low, nototals) ///
    sample(, statistic(frequency) place(seplabels)) ///
    sformat("n=%s" frequency) ///
    nformat(%2.0f fvpercent mean) nformat(%3.1f sd)  
    


    and the resulting output:
    Code:
    ----------------------------------------------
                                 Birthweight<2500g
                                    No       Yes  
                                  n=130     n=59  
    ----------------------------------------------
    Age of mother                24 (5.6) 22 (4.5)
    Race                                          
      White                      73 (56%) 23 (39%)
      Black                      15 (12%) 11 (19%)
      Other                      42 (32%) 25 (42%)
    Has history of hypertension                   
      No                        125 (96%) 52 (88%)
      Yes                          5 (4%)  7 (12%)
    ----------------------------------------------
    This is great when there aren't many variables. However, if there are many more variables, I prefer to display a single row for the binary variables, i.e. a single row for "History of hypertension" rather than 3 rows as shown above. I've attempted a work-around. Apart from only partially giving me what I want, it has introduced an undesirable consequence.

    In my work-around I'm treating history of hypertension as a continuous variable (mean=percentage).
    Code:
    *ht is a binary 0/1 variable. Multiplying by 100 so its mean is the same as percentage.
    gen ht100=ht*100
    lab var ht100 "History of hypertension"
    
    *Creating descriptive table.
    dtable age i.race ht100, by(low, nototals) ///
    sample(, statistic(frequency) place(seplabels)) ///
    sformat("n=%s" frequency) ///
    nformat(%2.0f fvpercent mean) nformat(%3.1f sd) /// 
    define(htperc=mean) sformat("(%s%%)" htperc) ///
    continuous(ht100, statistic(htperc))
    The resulting output is:
    Code:
    -----------------------------------------------------
                                  Birthweight<2500g      
                                  No             Yes     
                                 n=130          n=59     
    -----------------------------------------------------
    Age of mother           24 (5.6) (24%) 22 (4.5) (22%)
    Race                                                 
      White                       73 (56%)       23 (39%)
      Black                       15 (12%)       11 (19%)
      Other                       42 (32%)       25 (42%)
    History of hypertension         4 (4%)       12 (12%)
    -----------------------------------------------------
    My questions are:
    1. The percentage is repeated, first just the number and then in the specified format (#%). This is the case for both history of hypertension and mum's age (both treated as continuous). How do I tell Stata to display the mean only once within a cell? Can this be a different format for mum's age (showing just the mean, i.e. without (%)) vs history of hypertension (showing the mean with (%)).
    2. Is there a way to show the frequency of people with a history of hypertension?
    This is the output I would like to be able to produce:
    Code:
    ----------------------------------------------
                                 Birthweight<2500g      
                                    No       Yes     
                                  n=130     n=59     
    ----------------------------------------------
    Age of mother                24 (5.6) 22 (4.5) 
    Race                                                 
      White                      73 (56%) 23 (39%)
      Black                      15 (12%) 11 (19%)
      Other                      42 (32%) 25 (42%)
    History of hypertension        5 (4%)  7 (12%)
    ----------------------------------------------

    I'm aware my attempted work-around is convoluted. There may be a more straightforward way to do what I want that I missed when reading the help for -dtable-, in which case I will feel very silly.

    Kind regards,
    Suzanna



  • #2
    You can restrict factor variable levels. In your call to dtable, use 1.ht instead of i.ht.
    Then you can use collect style header to hide the factor's level in the row header with
    Code:
    collect style header ht, level(hide)
    collect preview
    Here is how I modified the original example
    Code:
    *Reading in the low birthweight dataset available on the Stata Press website.
    use https://www.stata-press.com/data/r18/lbw,clear
    
    *Adding value label to the low birthweight and hypertension variables.
    lab def noyes 0 No 1 Yes
    lab val low ht noyes
    
    *Creating descriptive table.
    dtable age i.race 1.ht, by(low, nototals) ///
    sample(, statistic(frequency) place(seplabels)) ///
    sformat("n=%s" frequency) ///
    nformat(%2.0f fvpercent mean) nformat(%3.1f sd)
    
    collect style header ht, level(hide)
    collect preview
    And here is the resulting table
    Code:
    . collect preview
    
    ---------------------------------------------
                                Birthweight<2500g
                                   No       Yes  
                                  n=130    n=59  
    ---------------------------------------------
    Age of mother               24 (5.6) 22 (4.5)
    Race                                         
      White                     73 (56%) 23 (39%)
      Black                     15 (12%) 11 (19%)
      Other                     42 (32%) 25 (42%)
    Has history of hypertension   5 (4%)  7 (12%)
    ---------------------------------------------

    Comment


    • #3
      Thanks Jeff for your quick and clear response. That's fabulous!

      Comment


      • #4
        I would like to do this, but to also show the p-value for the test comparing the two groups. However, when I add the tests option to the by() statement, the table shows the 0 row. Here is the code I am using,
        Code:
        *Reading in the low birthweight dataset available on the Stata Press website.
        use https://www.stata-press.com/data/r18/lbw,clear
        
        *Adding value label to the low birthweight and hypertension variables.
        lab def noyes 0 No 1 Yes
        lab val low ht noyes
        
        *Creating descriptive table.
        dtable age i.race i.ht, by(low, tests nototals) ///
        sample(, statistic(frequency) place(seplabels)) ///
        sformat("n=%s" frequency) ///
        nformat(%2.0f fvpercent mean) nformat(%3.1f sd) ///
        factor(ht, stat(fvfreq fvperc) test(pearson))
        
        
        collect style header ht, level(hide)
        collect preview
        and the output
        Code:
        . collect preview
        
        ----------------------------------------------------
                                        Birthweight<2500g   
                                        No       Yes    Test
                                      n=130     n=59        
        ----------------------------------------------------
        Age of mother                24 (5.6) 22 (4.5) 0.103
        Race                                                
          White                      73 (56%) 23 (39%) 0.082
          Black                      15 (12%) 11 (19%)      
          Other                      42 (32%) 25 (42%)      
        Has history of hypertension 125 (96%) 52 (88%) 0.036
                                       5 (4%)  7 (12%)      
        ----------------------------------------------------
        Last edited by amandacpac; 28 Jun 2023, 19:32.

        Comment


        • #5
          You need to specify the level of ht you want to show. The spots to change are
          Code:
          dtable age i.race i.ht, by(low, tests nototals) ///
          sample(, statistic(frequency) place(seplabels)) ///
          sformat("n=%s" frequency) ///
          nformat(%2.0f fvpercent mean) nformat(%3.1f sd) ///
          factor(ht, stat(fvfreq fvperc) test(pearson))
          Since the factor default statistics are fvfrequency and fvpercent and test is pearson, you can omit option factor() and just specify the level for factor ht.
          Code:
          dtable age i.race 1.ht, by(low, tests nototals) ///
          sample(, statistic(frequency) place(seplabels)) ///
          sformat("n=%s" frequency) ///
          nformat(%2.0f fvpercent mean) nformat(%3.1f sd)
          Note that I changed the i-dot notation i.ht to a one-dot 1.ht.
          Here is the resulting table
          Code:
          ---------------------------------------------------
                                         Birthweight<2500g   
                                         No       Yes    Test
                                        n=130    n=59        
          ---------------------------------------------------
          Age of mother               24 (5.6) 22 (4.5) 0.103
          Race                                               
            White                     73 (56%) 23 (39%) 0.082
            Black                     15 (12%) 11 (19%)      
            Other                     42 (32%) 25 (42%)      
          Has history of hypertension   5 (4%)  7 (12%) 0.036
          ---------------------------------------------------

          Comment


          • #6
            So, that i.ht was a typo. I fixed it in my code but apparently not in my comment. I get the same table that I posted above when I leave the factor() option in (with 1.ht). I get that I can omit that here, but if I use fishers exact or some other non-default, and thus need to include the factor() option, it seems to be messing it up.

            Comment


            • #7
              Here is how I changed your example, keeping option factor().
              Code:
              *Reading in the low birthweight dataset available on the Stata Press website.
              use https://www.stata-press.com/data/r18/lbw,clear
              
              *Adding value label to the low birthweight and hypertension variables.
              lab def noyes 0 No 1 Yes
              lab val low ht noyes
              
              *Creating descriptive table.
              dtable age i.race 1.ht, by(low, tests nototals) ///
              sample(, statistic(frequency) place(seplabels)) ///
              sformat("n=%s" frequency) ///
              nformat(%2.0f fvpercent mean) nformat(%3.1f sd) ///
              factor(1.ht, stat(fvfreq fvperc) test(pearson))
              
              
              collect style header ht, level(hide)
              collect preview
              Here is the resulting table
              Code:
              ---------------------------------------------------
                                             Birthweight<2500g   
                                             No       Yes    Test
                                            n=130    n=59        
              ---------------------------------------------------
              Age of mother               24 (5.6) 22 (4.5) 0.103
              Race                                               
                White                     73 (56%) 23 (39%) 0.082
                Black                     15 (12%) 11 (19%)      
                Other                     42 (32%) 25 (42%)      
              Has history of hypertension   5 (4%)  7 (12%) 0.036
              ---------------------------------------------------

              Comment


              • #8
                Ahhh. That makes total sense. Thank you!

                Comment

                Working...
                X