Announcement

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

  • Is it possible to replace cell contents of a table with a dash using collect?

    Firstly apologies for the many table and collect questions. Hopefully this is the last one for a little while. I greatly appreciate the detailed answers (a big thank-you to Jeff), which have helped me learn how to create various tables using the table, dtable and collect commands.

    Now the set up for my question.
    I've adapted exercise.dta to mirror a real dataset. Here's the code that does this followed by the data listing.

    Code:
    *_______________________________________________________________________________
    *This section sets up a dataset to mirror the structure of a real dataset.
    
    *Reading in the dataset.
    use https://www.stata-press.com/data/r18/exercise.dta
    keep if inlist(day, 0, 4, 6, 8, 12)
    
    *Replacing the variable program with group_allocation, where 1=intervention and 2=control.
    gen group_allocation=program
    lab var group_allocation "Group allocation"
    lab def grplbl 1 Intervention 2 Control
    lab val group_allocation grplbl
    drop program
    
    *Reshaping to wide format so there's one record per subject.
    reshape wide strength, i(id) j(day)
    
    *Adding variables re compliance to the intervention.
    set seed 20230627
    gen perc_attendance=runiform(30,100) if group_allocation==1
    gen perc_attend80 = perc_attendance<80 if !mi(perc_attendance)
    
    *Listing the data.
    list, noo ab(32) sepby(group_allocation)
    
      +----------------------------------------------------------------------------------------------------------------------+
      | id   strength0   strength4   strength6   strength8   strength12   group_allocation   perc_attendance   perc_attend80 |
      |----------------------------------------------------------------------------------------------------------------------|
      |  1          79          79          80          80           80       Intervention          90.85114               0 |
      |  2          83          85          85          86           87       Intervention          64.01286               1 |
      |  3          81          82          82          83           82       Intervention          73.99867               1 |
      |  4          81          81          82          82           81       Intervention          40.11504               1 |
      |  5          80          82          82          82           86       Intervention          75.97749               1 |
      |  6          76          76          76          76           75       Intervention          64.07038               1 |
      |  7          81          83          83          85           85       Intervention          31.36943               1 |
      |  8          77          79          79          81           81       Intervention          36.50623               1 |
      |  9          84          87          89           .           86       Intervention          98.55357               0 |
      | 10          74          78          78          79           78       Intervention          81.78549               0 |
      | 11          76          77          77          77           76       Intervention          75.26463               1 |
      | 12          84          86          85          86           86       Intervention          96.35122               0 |
      | 13          79          79          80          80           82       Intervention          78.54121               1 |
      | 14          78          77           .          75           76       Intervention          37.03198               1 |
      | 15          78          77          77          75           75       Intervention          52.49566               1 |
      | 16          84          85          85          85            .       Intervention          79.79121               1 |
      |----------------------------------------------------------------------------------------------------------------------|
      | 17          84          84          83          83           84            Control                 .               . |
      | 18          74          75          78          75           76            Control                 .               . |
      | 19          83          82          81           .            .            Control                 .               . |
      | 20          86          87          87          87           86            Control                 .               . |
      | 21          82          84          85          84           86            Control                 .               . |
      | 22          79          79          79          80           80            Control                 .               . |
      | 23          79          79          81          81            .            Control                 .               . |
      | 24          87          91          90          91            .            Control                 .               . |
      | 25          81          81          82          82           83            Control                 .               . |
      | 26          82           .          84          86            .            Control                 .               . |
      | 27          79          80          81          81            .            Control                 .               . |
      | 28          79          81          82          83            .            Control                 .               . |
      | 29          83          84          84          84           83            Control                 .               . |
      | 30          81          82          84          83           85            Control                 .               . |
      | 31          78          79          79          78           79            Control                 .               . |
      | 32          83          82          84          84           84            Control                 .               . |
      | 33          80          79          81           .           80            Control                 .               . |
      | 34          80          82          82          81           81            Control                 .               . |
      | 35          85          87          86          86           86            Control                 .               . |
      | 36          77          80          81          82           82            Control                 .               . |
      | 37          80          80          81          81           83            Control                 .               . |
      +----------------------------------------------------------------------------------------------------------------------+
    As you can see, the variables perc_attendance and perc_attend80 are relevant only for the intervention group.

    Next is my code that creates the table followed by the table.
    Code:
    *_______________________________________________________________________________
    *Creating the table via dtable and collect commands.
    
    *Clearing any collections that may be in Stata's memory.
    collect clear
    
    *Creating descriptive table.
    dtable strength0 strength4 strength6 strength8 perc_attendance 1.perc_attend80, by(group_allocation,nototals) ///
    sample(, statistic(frequency) place(seplabels)) ///
    sformat("n=%s" frequency) ///
    define(rangei = min max, delimiter("-")) sformat("[%s]" rangei) ///
    continuous(strength0 strength4 strength6 strength8 perc_attendance, statistic(mean sd rangei)) ///
    nformat(%2.0f fvpercent mean median sd rangei) nformat(%3.1f sd) ///
    title(Table 4: Compliance) ///
    titlestyles(font(Calibri, size(12) bold))
    
    foreach x in strength {
        collect label levels var `x'0  "Baseline" ///
                                 `x'4  "Day 4" ///
                                 `x'6  "Day 6" ///
                                 `x'8  "Day 8",modify
    }
    
    collect addtags vargrp[Strength measurement, Mean (SD) [Range]], fortags(var[strength0 strength4 strength6 strength8])
    collect label levels var perc_attendance "Percentage program completed, Mean (SD) [Range]"
    collect label levels var 1.perc_attend80 "Completed<80% of the program, n (%)"
    collect style header ht, level(hide)
    
    collect layout (vargrp#var var[perc_attendance perc_attend80]) (group_allocation#result)
    
    
    Table 4: Compliance
    ----------------------------------------------------------------------------------
                                                             Group allocation         
                                                       Intervention        Control    
    ----------------------------------------------------------------------------------
    Strength measurement, Mean (SD) [Range]                                           
      Baseline                                       80 (3.1) [74-84] 81 (3.1) [74-87]
      Day 4                                          81 (3.6) [76-87] 82 (3.6) [75-91]
      Day 6                                          81 (3.7) [76-89] 83 (2.9) [78-90]
      Day 8                                          81 (3.8) [75-86] 83 (3.5) [75-91]
    Percentage program completed, Mean (SD) [Range] 67 (21.9) [31-99]      . (.) [.-.]
    Completed<80% of the program, n (%)                      12 (75%)           0 (.%)
    ----------------------------------------------------------------------------------
    The last two rows of the table are relevant only to the intervention group. Is it possible to replace the contents of their cells in the Control column with a single dash using a collect command? If not, I can do so via putdocx but I want to limit my use of putdocx which is more fiddly.

    Kind regards,
    Suzanna
    Last edited by Suzanna Vidmar; 27 Jun 2023, 05:07.

  • #2
    There is no facility to override the cell contents when it is produced by a composite result.
    The putdocx route might be easier, but another way is to build the table is 2 steps. One using the Intervention subset only, then combining those results to strength measurements.
    Here is how I modified your code to accomplish this, resulting in empty cells for the Control group where there are missing values (dots) above.
    Code:
    *_______________________________________________________________________________
    *Creating the table via dtable and collect commands.
    
    *Clearing any collections that may be in Stata's memory.
    collect clear
    
    *Intervention only calculations.
    dtable perc_attendance 1.perc_attend80 ///
        if group_allocation == 1, ///
        continuous(, statistic(mean sd min max)) ///
        name(InterventionOnly)
    collect addtags group_allocation[1]
    collect query composite _dtable_stats
    
    *Creating descriptive table.
    dtable strength0 strength4 strength6 strength8, by(group_allocation,nototals) ///
    sample(, statistic(frequency) place(seplabels)) ///
    sformat("n=%s" frequency) ///
    define(rangei = min max, delimiter("-")) sformat("[%s]" rangei) ///
    continuous(strength0 strength4 strength6 strength8, statistic(mean sd rangei)) ///
    nformat(%2.0f fvpercent mean median sd rangei) nformat(%3.1f sd) ///
    title(Table 4: Compliance) ///
    titlestyles(font(Calibri, size(12) bold))
    
    *Combine above collections.
    collect combine comb = DTable InterventionOnly
    collect style autolevels perc_attendance 1.perc_attend80
    collect query composite _dtable_stats
    collect composite define ///
        _dtable_stats =    frequency ///
                mean ///
                sd ///
                rangei ///
                fvfrequency ///
                fvpercent ///
                , ///
        trim ///
        replace
    
    foreach x in strength {
        collect label levels var `x'0  "Baseline" ///
                                 `x'4  "Day 4" ///
                                 `x'6  "Day 6" ///
                                 `x'8  "Day 8",modify
    }
    
    collect addtags vargrp[Strength measurement, Mean (SD) [Range]], fortags(var[strength0 strength4 strength6 strength8])
    collect label levels var perc_attendance "Percentage program completed, Mean (SD) [Range]"
    collect label levels var 1.perc_attend80 "Completed<80% of the program, n (%)"
    collect style header ht, level(hide)
    
    collect layout (vargrp#var var[perc_attendance perc_attend80]) (group_allocation#result)
    Here is the resulting table
    Code:
    Table 4: Compliance
    ----------------------------------------------------------------------------------
                                                             Group allocation         
                                                       Intervention        Control    
                                                         Summary           Summary    
    ----------------------------------------------------------------------------------
    Strength measurement, Mean (SD) [Range]                                           
      Baseline                                       80 (3.1) [74-84] 81 (3.1) [74-87]
      Day 4                                          81 (3.6) [76-87] 82 (3.6) [75-91]
      Day 6                                          81 (3.7) [76-89] 83 (2.9) [78-90]
      Day 8                                          81 (3.8) [75-86] 83 (3.5) [75-91]
    Percentage program completed, Mean (SD) [Range] 67 (21.9) [31-99]                 
    Completed<80% of the program, n (%)                      12 (75%)                 
    ----------------------------------------------------------------------------------

    Comment


    • #3
      Thanks again Jeff!!! I did think about creating two tables and combining them but wanted to try the easier option first in case it was possible to override the cell contents.

      I now realize the contents of _dtable_stats are determined by the previous dtable command, much like stored results contain the results of the last statistical command executed.

      I wouldn't have thought to run this command, so that's very helpful to learn.
      Code:
      collect addtags group_allocation[1]
      I assume the by(group_allocation) option is what creates the group_allocation dimension, which of course isn't in the intervention-only table.


      I don't know what this command is for. Why did you include it? I ran my do-file without it and it produced the same table.
      Code:
      collect style autolevels perc_attendance 1.perc_attend80

      Both of these commands produce the same table. Maybe I don't need "1." in front of perc_attend80 because there's only one level of perc_attend80 in the collection. Is that right?
      Code:
      collect layout (vargrp#var var[perc_attendance 1.perc_attend80]) (group_allocation#result)
      collect layout (vargrp#var var[perc_attendance   perc_attend80]) (group_allocation#result)

      For the benefit of anyone reading this post, there's a line of code that doesn't belong. I forgot to delete it before posting.
      Code:
      collect style header ht, level(hide)
      Cheers,
      Suzanna

      Comment


      • #4
        Glad to help.

        Please ignore the line
        Code:
        collect style autolevels perc_attendance 1.perc_attend80
        you are correct, it was unnecessary given your var specification in the layout -- plus it is missing the var dimension after the keyword autolevels. That line should have been
        Code:
        collect style autolevels var perc_attendance 1.perc_attend80
        then you would not need to specify the levels of var in the layout.

        Comment


        • #5
          Thanks Jeff. I think understand but I would also need to change my layout or make other edits to my do-file so that the strength measure rows aren't repeated. See the code and table below where I removed the levels from var.
          Obviously there's still lots more for me to learn. I appreciate your help with this.

          Code:
          . collect layout (vargrp#var var) (group_allocation#result)
          
          Collection: comb
                Rows: vargrp#var var
             Columns: group_allocation#result
             Table 1: 12 x 2
          
          Table 4: Compliance
          ----------------------------------------------------------------------------------
                                                                   Group allocation         
                                                             Intervention        Control    
                                                               Summary           Summary    
          ----------------------------------------------------------------------------------
          Strength measurement, Mean (SD) [Range]                                           
            Baseline                                       80 (3.1) [74-84] 81 (3.1) [74-87]
            Day 4                                          81 (3.6) [76-87] 82 (3.6) [75-91]
            Day 6                                          81 (3.7) [76-89] 83 (2.9) [78-90]
            Day 8                                          81 (3.8) [75-86] 83 (3.5) [75-91]
          N                                                            n=16                 
          Baseline                                         80 (3.1) [74-84] 81 (3.1) [74-87]
          Day 4                                            81 (3.6) [76-87] 82 (3.6) [75-91]
          Day 6                                            81 (3.7) [76-89] 83 (2.9) [78-90]
          Day 8                                            81 (3.8) [75-86] 83 (3.5) [75-91]
          Percentage program completed, Mean (SD) [Range] 67 (21.9) [31-99]                 
          Completed<80% of the program, n (%)                      12 (75%)                 
          ----------------------------------------------------------------------------------
          Cheers,
          Suzanna

          Comment


          • #6
            Yes, I should have run the code changes I suggested at the end of #4 before I posted that last part.

            Comment


            • #7
              No problem.

              Comment

              Working...
              X