Announcement

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

  • Bolding row/colname dimensions but not their levels

    Hello all: This has been irking me for a while but I cannot get it to work. I need the row variable labels (not each of their levels) bolded in the final word table I am create with the dtable.
    Would like some help with getting the code right. I can get until collect style cell [rowheader] but it is not working as I want it. Below I would like "t2" and "Baseline parms. [IQR]" to be in bold.

    Code:
    sysuse auto, clear
    collect clear 
    putdocx clear
    
    **# Table 1 
    *----------------------
    gen turnbinary = turn > 35
    lab def tlab 0 "Low Turn" 1 "High Turn"
    lab val turnbinary tlab
    
    
    local binvars "i.turnbinary"
    
    dtable c.weight `binvars', by(foreign, tests nototals nomissing) column(by(hide)) ///
            continuous(weight length mpg, statistics(p50 iqi))     ///
                define(iqi = min max, delimiter("-"))             ///
                sformat("[%s]" iqi)                              ///
                nformat(%5.0f iqi)                                 ///
                nformat(%3.1f p50)                                 ///
            factor(`binvars', statistics( fvfreq fvpercent) test(pearson) font( arial,nobold)) ///
            sample(Sample, statistic(frequency percent) place(seplabels)) sformat("N=%s" frequency) ///
    
    
    // Add a tag to nest contvars into a group under Baseline labs
    *------------------------------------------------------------
    collect addtags vargrp[Baseline parms. [IQR]], fortags(var[length mpg])
    
    // Bold column headers and stack 
    *-------------------------------
    collect style cell cell_type[column-header], font(arial, bold)
    collect style row stack, truncate(head)
    collect style cell cell_type[row-header]#turnbinary, font(arial, bold)
    
    
    // Final layout & export
    *-----------------------
    collect layout (vargrp#var var[`binvars']) (foreign#result#_dtable_sample_dim)
    collect preview
    
    collect style putdocx, layout(autofitcontents) ///
    
    collect export "./test.docx", replace

  • #2
    Thanks for the reproducible example. Try something like:

    Code:
    sysuse auto, clear
    collect clear 
    putdocx clear
    
    **# Table 1 
    *----------------------
    gen turnbinary = turn > 35
    lab def tlab 0 "Low Turn" 1 "High Turn"
    lab val turnbinary tlab
    
    
    local binvars "i.turnbinary"
    
    dtable c.weight `binvars', by(foreign, tests nototals nomissing) column(by(hide)) ///
            continuous(weight length mpg, statistics(p50 iqi))     ///
                define(iqi = min max, delimiter("-"))             ///
                sformat("[%s]" iqi)                              ///
                nformat(%5.0f iqi)                                 ///
                nformat(%3.1f p50)                                 ///
            factor(`binvars', statistics( fvfreq fvpercent) test(pearson) font( arial,nobold)) ///
            sample(Sample, statistic(frequency percent) place(seplabels)) sformat("N=%s" frequency) ///
    
    
    // Add a tag to nest contvars into a group under Baseline labs
    *------------------------------------------------------------
    collect addtags vargrp[Baseline parms. [IQR]], fortags(var[length mpg])
    collect addtags vargrp2[turbinary], fortags(turnbinary[0 1])
    // Bold column headers and stack 
    *-------------------------------
    collect style cell cell_type[column-header], font(arial, bold)
    collect style cell vargrp#cell_type[row-header], font(arial,bold)
    collect style cell vargrp2#cell_type[row-header], font(arial,bold)
    collect style cell var[length mpg]#cell_type[row-header], font(arial,nobold)
    collect style cell turnbinary[0 1]#cell_type[row-header], font(arial,nobold)
    collect style row stack, truncate(head)
    
    // Final layout & export
    *-----------------------
    collect layout (vargrp#var vargrp2#turnbinary) (foreign#result#_dtable_sample_dim)
    collect preview
    
    collect style putdocx, layout(autofitcontents) ///
    
    collect export "./test.docx", replace
    Res.:

    Click image for larger version

Name:	Capture.PNG
Views:	1
Size:	18.5 KB
ID:	1737223

    Comment


    • #3
      Thanks much for this, Andrew Musau. This solves the last piece for me in creating my ideal Table 1. I kind of get the logic of how the tags work. Wish -dtable- had an option built-in to do this like Daniel Sjobergs' R::gtsummary does automatically. Perhaps I will throw in a request in the sticky page for wish lists. For now, I will try to see how I can loop your process for any categorical variable dimension names in rows in a generic dtable.

      Comment


      • #4
        Andrew provides the best (to my mind) working solution to the problem of
        bolding factor variable names/labels but not their levels.

        In the following, I provide a slightly modified version of Andrew's idea
        that uses a few subtle features of collect that I want to make
        better known in this community.

        Girish introduces a variable grouping dimension for the continuous
        variables to the collection and Andrew expands on this providing a
        second grouping dimension for the factor variables. We can consolidate
        these two dimensions into one, but use a different dimension name that has
        some helpful built-in features. The idea is to replace vargrp and
        vargrp2 with roweq, fill it with a custom level like Girish
        does originally, and the factor variables names like in Andrew's code.
        This simplifies some style settings and the layout. Also collect
        will pull variable labels from the current frame (dataset) for levels of
        roweq that match variable names.

        I also add/modify some local macros for the variable list groups. The
        weight variable that was specified in the call to dtable
        somehow got lost in the example code, so I add a macro for the
        continuous variables that allows for better targeting and tagging.
        I also treat the binvars macro as if it contains a list of factor
        variables, providing a loop for adding factor variable specific levels of
        roweq that will be targeted for bold in the row header styles.

        Code:
        sysuse auto, clear
        collect clear
        putdocx clear
        
        **# Table 1
        *----------------------
        gen turnbinary = turn > 35
        lab def tlab 0 "Low Turn" 1 "High Turn"
        lab val turnbinary tlab
        * label this variable; later -roweq- will pick it up too
        lab var turnbinary "Turn circle"
        
        * use macro for continuous variables, -weight- got lost in the original code
        local convars weight length mpg
        
        * no need for 'i.' here, we will add it to a spot later
        local binvars turnbinary
        
        * variables specified in options -continuous()- and -factor()- do not
        * need to be specified in the varlist unless you want a special variable
        * order that is otherwise too difficult to get using the options
        dtable, by(foreign, tests nototals nomissing)        ///
            column(by(hide))                ///
            continuous(`convars', statistics(p50 iqi))    ///
            define(iqi = min max, delimiter("-"))        ///
            sformat("[%s]" iqi)                ///
            nformat(%5.0f iqi)                ///
            nformat(%3.1f p50)                ///
            factor(`binvars',                ///
                statistics(fvfreq fvpercent)        ///
                test(pearson)                ///
            )                        ///
                sample(Sample,                    ///
                statistic(frequency percent)        ///
                place(seplabels)            ///
            )                        ///
            sformat("N=%s" frequency)
        
        *------------------------------------------------------------
        * Add -roweq- tag to nest vars into groups; -roweq- is a special
        * dimension that will grab variable labels for it's levels that match
        * variable names in the current frame
        collect addtags roweq[Baseline parms. [IQR]], fortags(var[`convars'])
        foreach b of local binvars {
            collect addtags roweq[`b'], fortags(var[i.`b'])
            * hide this factor variable's title since we plan to use this
            * -roweq- level to title this variable in the header
            collect style header `b', title(hide)
        }
        collect style header roweq, title(hide) level(label)
        
        *-------------------------------
        * bold all the column headers
        collect style cell cell_type[column-header], font(arial, bold)
        * bold the levels of -roweq-
        collect style cell roweq#cell_type[row-header], font(arial, bold)
        * unbold the variable names/labels
        collect style cell var#cell_type[row-header], font(arial, nobold)
        collect style row stack, truncate(head)
        
        // Final layout & export
        *-----------------------
        collect layout (roweq#var) (foreign#result#_dtable_sample_dim)
        
        collect style putdocx, layout(autofitcontents) ///
        
        collect export "./test.docx", replace
        I additionally exported to HTML in my Stata session, here is a
        screenshot of the resul from my browser.


        Click image for larger version

Name:	Screenshot 2023-12-15 at 11.16.17 AM.png
Views:	1
Size:	57.6 KB
ID:	1737285

        Comment


        • #5
          Love it, Jeff Pitblado (StataCorp) . Good to learn about -roweq-. Between #2 from Andrew Musau and your #3, I envisage that the much of your code should be quite commutable across different datasets without having rewrite those -collect styles-(arial, bold) lines for each binvar/contvar groups I may want to bold.

          Comment


          • #6
            @Jeff Pitblado (StataCorp) If we want to display categories with zero frequencies (for categorical variables), how do we go about that with this code?

            Comment


            • #7
              I love this command—it’s exactly what I need! However, I’m struggling to apply it to my own dataset. My code is the following, and I would like the variable names of all factor variables to appear in bold, but not their values. The continuous variable hourly_wage_eb should have its own bold heading: “Hourly wage.” I tried to apply the above code, but it doesn´t work. My "fvars" are not binary but with up tp five levels/dimensions. Any held would be appreciated, thx!

              collect clear
              local fvars SD14 SD17 SD18 SD5_h SD6_h LK_group SD26 SD27
              local cvars hourly_wage_eb
              collect clear
              dtable ///
              $fvars ///
              $cvars if inlist(LK_group, 1, 2), ///
              by(LK_group, nototals) column(by(hide)) ///
              sample(, place(seplabels) ) ///
              continuous(, statistics(p50 mean)) ///
              factor(, statistic(fvfrequency fvpercent)) ///
              export("table1", as(docx) replace)

              collect style cell var, font(Arial, size(10))
              collect style cell result[p50 mean], nformat(%3.1f)
              collect style cell result[fvpercent], nformat(%16.2fc)
              collect style cell cell_type[column-header], font(Arial, size(11) color(black) bold)
              collect style cell cell_type[row-header], halign(right)
              collect style row stack, spacer

              collect export "table1.docx", as(docx) replace


              Comment


              • #8


                You can add bolded levels using collect label. Using the example in #2:

                Code:
                sysuse auto, clear
                collect clear
                putdocx clear
                
                **# Table 1
                *----------------------
                gen turnbinary = turn > 35
                lab def tlab 0 "Low Turn" 1 "High Turn"
                lab val turnbinary tlab
                
                
                local binvars "i.turnbinary"
                
                dtable c.weight `binvars', by(foreign, tests nototals nomissing) column(by(hide)) ///
                        continuous(weight length mpg, statistics(p50 iqi))     ///
                            define(iqi = min max, delimiter("-"))             ///
                            sformat("[%s]" iqi)                              ///
                            nformat(%5.0f iqi)                                 ///
                            nformat(%3.1f p50)                                 ///
                        factor(`binvars', statistics( fvfreq fvpercent) test(pearson) font( arial,nobold)) ///
                        sample(Sample, statistic(frequency percent) place(seplabels)) sformat("N=%s" frequency) ///
                
                
                // Add a tag to nest contvars into a group under Baseline labs
                *------------------------------------------------------------
                collect addtags vargrp[Baseline parms. [IQR]], fortags(var[length mpg])
                collect addtags vargrp2[turbinary], fortags(turnbinary[0 1])
                // Bold column headers and stack
                *-------------------------------
                collect style cell cell_type[column-header], font(arial, bold)
                collect style cell vargrp#cell_type[row-header], font(arial,bold)
                collect style cell vargrp2#cell_type[row-header], font(arial,bold)
                collect style cell var[length mpg]#cell_type[row-header], font(arial,nobold)
                collect style cell turnbinary[0 1]#cell_type[row-header], font(arial,nobold)
                collect style row stack, truncate(head)
                
                // Final layout & export
                *-----------------------
                collect layout (vargrp#var vargrp2#turnbinary) (foreign#result#_dtable_sample_dim)
                collect preview
                
                collect levelsof turnbinary
                collect label levels turnbinary 0 "{bf:Low turn}", modify
                collect label levels turnbinary 1 "{bf:High turn}", modify
                collect preview
                Res.:


                Click image for larger version

Name:	Capture.PNG
Views:	1
Size:	20.3 KB
ID:	1782537




                Alternatively, use collect style directly as specified in the sequence:

                Code:
                sysuse auto, clear
                collect clear 
                putdocx clear
                
                **# Table 1 
                *----------------------
                gen turnbinary = turn > 35
                lab def tlab 0 "Low Turn" 1 "High Turn"
                lab val turnbinary tlab
                
                
                local binvars "i.turnbinary"
                
                dtable c.weight `binvars', by(foreign, tests nototals nomissing) column(by(hide)) ///
                        continuous(weight length mpg, statistics(p50 iqi))     ///
                            define(iqi = min max, delimiter("-"))             ///
                            sformat("[%s]" iqi)                              ///
                            nformat(%5.0f iqi)                                 ///
                            nformat(%3.1f p50)                                 ///
                        factor(`binvars', statistics( fvfreq fvpercent) test(pearson) font( arial,nobold)) ///
                        sample(Sample, statistic(frequency percent) place(seplabels)) sformat("N=%s" frequency) ///
                
                
                // Add a tag to nest contvars into a group under Baseline labs
                *------------------------------------------------------------
                collect addtags vargrp[Baseline parms. [IQR]], fortags(var[length mpg])
                collect addtags vargrp2[turbinary], fortags(turnbinary[0 1])
                // Bold column headers and stack 
                *-------------------------------
                collect style cell cell_type[column-header], font(arial, bold)
                collect style cell vargrp#cell_type[row-header], font(arial,bold)
                collect style cell vargrp2#cell_type[row-header], font(arial,bold)
                collect style cell var[length mpg]#cell_type[row-header], font(arial,nobold)
                collect style cell turnbinary[0 1]#cell_type[row-header], font(arial,bold)
                collect style row stack, truncate(head)
                
                // Final layout & export
                *-----------------------
                collect layout (vargrp#var vargrp2#turnbinary) (foreign#result#_dtable_sample_dim)
                collect preview
                As usual, we need a reproducible example just in case you cannot achieve this result using your dataset. See FAQ Advice #12 for details on this.
                Last edited by Andrew Musau; 21 Oct 2025, 08:39.

                Comment


                • #9
                  This works perfectly well, thanks Andrew Musau !!! As I have not only one but several (factor) Variables, I would like to add a question: Is there any possibilty to put all my variables into a loop or do I have to set bold column headers for each variable and manual. With the modified code, I can set bold columns headers only for one factor variable and the continous variable. Is there a way to loop all "fvars"?

                  local fvars SD14 SD17 SD18 SD5_h SD6_h LK_group SD26 SD27
                  local cvars hourly_wage_eb


                  collect clear


                  dtable ///
                  $fvars ///
                  $cvars if inlist(LK_group, 1, 2), ///
                  by(LK_group, nototals) column(by(hide)) ///
                  sample(, place(seplabels) ) ///
                  continuous(, statistics(p50 mean)) ///
                  factor(, statistic(fvfrequency fvpercent)) ///
                  export("table1", as(docx) replace)

                  collect style cell var, font(Arial, size(10))
                  collect style cell result[p50 mean], nformat(%3.1f)
                  collect style cell result[fvpercent], nformat(%16.2fc)
                  collect style cell cell_type[column-header], font(Arial, size(11) color(black) bold)
                  collect style cell cell_type[row-header], halign(right)
                  collect style row stack, spacer



                  // Add a tag to nest contvars into a group under Baseline labs
                  *------------------------------------------------------------
                  collect addtags vargrp2[Familienstand], fortags(SD14[1 2 3 4 5 70 80])
                  collect addtags vargrp[Continous], fortags(var[hourly_wage_eb])


                  // Bold column headers and stack
                  *-------------------------------
                  collect style cell cell_type[column-header], font(arial, bold)

                  collect style cell vargrp2#cell_type[row-header], font(arial,bold)
                  collect style cell vargrp#cell_type[row-header], font(arial,bold)

                  collect style cell SD14[1 2 3 4 5 70 80]#cell_type[row-header], font(arial,nobold)
                  collect style cell var[hourly_wage_eb]#cell_type[row-header], font(arial,nobold)

                  collect style row stack, truncate(head)


                  // Final layout & export
                  *-----------------------
                  collect layout (vargrp2#SD14 vargrp#var ) (LK_group#result#_dtable_sample_dim)
                  collect preview

                  Comment


                  • #10
                    I guess the following should work:

                    Code:
                    foreach var of local fvars{
                        collect style cell `var'[]#cell_type[row-header], font(arial,bold)
                    }
                    Make sure the local fvars is defined when running the forvalues loop.

                    Comment


                    • #11
                      Originally posted by Andrew Musau View Post
                      I guess the following should work:

                      Code:
                      foreach var of local fvars{
                      collect style cell `var'[]#cell_type[row-header], font(arial,bold)
                      }
                      Make sure the local fvars is defined when running the forvalues loop.
                      Tanks again, Andrew Musau! Unfortunately that doesn' t work. Maybe I appended the loop on the wrong place....anayways: I can do that step by step, so: Thanks again for your support!

                      Comment


                      • #12
                        In #9 you have

                        local fvars SD14 SD17 SD18 SD5_h SD6_h LK_group SD26 SD27
                        and then you reference a global "fvars"

                        dtable ///
                        $fvars ///
                        So there is a mismatch there. Being explicit may do the trick. Try:


                        Code:
                        foreach var in SD14 SD17 SD18 SD5_h SD6_h LK_group SD26 SD27{
                            collect style cell `var'[]#cell_type[row-header], font(arial,bold)
                        }

                        Comment


                        • #13
                          Originally posted by Andrew Musau View Post
                          In #9 you have



                          and then you reference a global "fvars"



                          So there is a mismatch there. Being explicit may do the trick. Try:


                          Code:
                          foreach var in SD14 SD17 SD18 SD5_h SD6_h LK_group SD26 SD27{
                          collect style cell `var'[]#cell_type[row-header], font(arial,bold)
                          }

                          Hm, seems to be more tricky than expected...honestely I am not sure, where I have to append that loop (obviously not at the end) - and as "collect addtags" and "vargrp" is defined only for SD14 and hourly_wage_eb only, this may not work...but I won´t waste your time as I can try to append the command without looping the variables (and instead add them step by step). Thx again!

                          Comment


                          • #14
                            Are you able to share a sample of your data? About 20 observations will do. You can do so by copying and pasting the output from the following:

                            Code:
                            dataex SD14 SD17 SD18 SD5_h SD6_h LK_group SD26 SD27 hourly_wage_eb LK_group in 1/20

                            Comment


                            • #15
                              You mean like this?

                              . dataex SD14 SD17 SD18 SD5_h SD6_h LK_group SD26 SD27 hourly_wage_eb LK_group in 1/20

                              ----------------------- copy starting from the next line -----------------------
                              Code:
                              * Example generated by -dataex-. For more info, type help dataex
                              clear
                              input byte(SD14 SD17 SD18 SD5_h SD6_h) float LK_group byte(SD26 SD27) float hourly_wage_eb
                              1 1 2 3 4 3 1  1  .
                              2 1 2 3 4 4 3  3  .
                              3 1 2 2 1 4 3  3 12
                              1 1 2 3 1 . 1  1  .
                              5 1 1 3 4 1 1  3 42
                              3 1 2 3 1 3 1  1 29
                              3 1 2 1 2 1 1  3 27
                              2 1 2 3 4 4 3  3 14
                              3 3 2 3 4 1 1  3  8
                              3 1 2 3 4 1 1  3 20
                              3 1 2 3 4 1 1  3 33
                              3 1 2 3 4 1 1  3 12
                              3 1 2 3 4 3 1  1  .
                              3 1 2 3 4 5 5 80  .
                              3 1 2 3 3 1 1  3 37
                              3 1 2 2 1 3 1  1 15
                              3 1 2 3 4 3 1  1 33
                              4 1 1 2 4 4 3  3  .
                              5 1 2 3 4 1 1  3  7
                              3 3 1 1 4 1 1  3 32
                              end
                              label values SD14 SD14_mod
                              label def SD14_mod 1 "Ledig", modify
                              label def SD14_mod 2 "Lebe mit Partner bzw. Partnerin in einem Haushalt", modify
                              label def SD14_mod 3 "Verheiratet oder eingetragene Partnerschaft", modify
                              label def SD14_mod 4 "Verwitwet", modify
                              label def SD14_mod 5 "Geschieden", modify
                              label values SD17 SD17_mod
                              label def SD17_mod 1 "In Deutschland / Im Gebiet des heutigen Deutschlands", modify
                              label def SD17_mod 3 "Im Ausland / In einem anderen Land", modify
                              label values SD18 SD18_mod
                              label def SD18_mod 1 "Ja, mindestens ein Elternteil wurde ausserhalb von Deutschland geboren", modify
                              label def SD18_mod 2 "Nein, beide Elternteile wurden in Deutschland bzw. den ehemaligen deutschen Staatsgebieten geboren", modify
                              label values SD5_h SD5_hlbl_mod
                              label def SD5_hlbl_mod 1 "kein/HS/sonstiges", modify
                              label def SD5_hlbl_mod 2 "MR", modify
                              label def SD5_hlbl_mod 3 "FHR/Abi", modify
                              label values SD6_h SD6_hlbl_mod
                              label def SD6_hlbl_mod 1 "Lehre/Berufsausbildung/anderer berufsqual.", modify
                              label def SD6_hlbl_mod 2 "Meister- oder Technikerausbildung", modify
                              label def SD6_hlbl_mod 3 "Abschluss einer Berufsakademie oder einer dualen Hochschule", modify
                              label def SD6_hlbl_mod 4 "Uni/(F)H-Abschluss", modify
                              label values LK_group LK_grouplbl
                              label def LK_grouplbl 1 "(Solo-)Selbständig", modify
                              label def LK_grouplbl 3 "Hybride Beschäftigung", modify
                              label def LK_grouplbl 4 "Rente", modify
                              label def LK_grouplbl 5 "sonstiges/unklar", modify
                              label values SD26 SD26_mod
                              label def SD26_mod 1 "Erwerbstaetig", modify
                              label def SD26_mod 3 "In Rente", modify
                              label def SD26_mod 5 "Nicht erwerbstaetig", modify
                              label values SD27 SD27_mod
                              label def SD27_mod 1 "Ja, ein Beschaeftigungsverhaeltnis als Angestellter oder Beamter", modify
                              label def SD27_mod 3 "Nein, kein Beschaeftigungsverhaeltnis als Angestellter oder Beamter", modify
                              label def SD27_mod 80 "Ausgefiltert", modify
                              ------------------ copy up to and including the previous line ------------------


                              Originally posted by Andrew Musau View Post
                              Are you able to share a sample of your data? About 20 observations will do. You can do so by copying and pasting the output from the following:

                              Code:
                              dataex SD14 SD17 SD18 SD5_h SD6_h LK_group SD26 SD27 hourly_wage_eb LK_group in 1/20

                              Comment

                              Working...
                              X