Home  /  Resources & support  /  FAQs  /  collect get for creating a customized table layout

How can I create table layouts from scratch by using collect get?

Title   collect get for creating a customized table layout
Author Chris Cheng, StataCorp

Creating tables and customizing them to your preferred style has been made easy with features introduced in Stata 17. The reimagined table command can create tables of summary statistics, estimation results, and tables with returned results. Additionally, the collect suite of commands can be used to style your tables and export them. You may find that many of the tables you have in mind can be created with table. However, if you want more control over the layout of the table, you can manually build your table with collect get. In the examples below, we demonstrate how you can create a custom table layout with collect get.

In this first example, we show you how to create a table with summary statistics. Let’s first call the summarize command.

. sysuse auto
(1978 automobile data)

. summarize price - gear_ratio

Variable Obs Mean Std. dev. Min Max
price 74 6165.257 2949.496 3291 15906
mpg 74 21.2973 5.785503 12 41
rep78 69 3.405797 .9899323 1 5
headroom 74 2.993243 .8459948 1.5 5
trunk 74 13.75676 4.277404 5 23
weight 74 3019.459 777.1936 1760 4840
length 74 187.9324 22.26634 142 233
turn 74 39.64865 4.399354 31 51
displacement 74 197.2973 91.83722 79 425
gear_ratio 74 3.014865 .4562871 2.19 3.89

The table layout is defined by the rows and columns. We can create this table layout from scratch by collecting each result and tagging it as a row or column component using collect get. Let's try to create the row for price:

. collect get Variable = "Obs",       tags(Col[1])

. collect get Variable = "Mean",      tags(Col[2])

. collect get Variable = "Std. dev.", tags(Col[3])

. collect get Variable = "Min",       tags(Col[4])

. collect get Variable = "Max",       tags(Col[5])

. collect get price    = "74",        tags(Col[1])

. collect get price    = "6165.257",  tags(Col[2])

. collect get price    = "2949.496",  tags(Col[3])

. collect get price    = "3291",      tags(Col[4])

. collect get price    = "15906",     tags(Col[5])

The collect get command is creating results called Variable and price that are equal to the expressions we specify. With the tags() option, we are adding a tag to each result so that we can easily group items with the same tag. Col is the name we chose for our group of items, and the numbers in brackets indicate the level of Col.

We then lay out our table by placing the results on the rows and the levels of Col on the columns.

. collect layout (result) (Col)

Collection: default
      Rows: result
   Columns: Col
   Table 1: 2 x 5

1 2 3 4 5
Variable Obs Mean Std. dev. Min Max
price 74 6165.257 2949.496 3291 15906

We can automate this process to add results for other variables by writing a loop with foreach:

. foreach i of varlist mpg - gear_ratio{  
  2.         quietly summarize `i'
  3.         collect get `i' = "`r(N)'",                   tags(Col[1])
  4.         collect get `i' = "`:display %9.0g r(mean)'", tags(Col[2])
  5.         collect get `i' = "`:display %9.0g r(sd)'",   tags(Col[3])
  6.         collect get `i' = "`:display %9.0g r(min)'",  tags(Col[4])
  7.         collect get `i' = "`:display %9.0g r(max)'",  tags(Col[5])
  8. }

In this loop, we are creating the results named mpg, rep78, etc. Note that all the means will be tagged with level 2 of Col, all the standard deviations will be tagged with level 3 of Col, and so on.

. collect layout (result) (Col)

Collection: default
      Rows: result
   Columns: Col
   Table 1: 11 x 5

1 2 3 4 5
Variable Obs Mean Std. dev. Min Max
price 74 6165.257 2949.496 3291 15906
mpg 74 21.2973 5.785503 12 41
rep78 69 3.405797 .9899323 1 5
headroom 74 2.993243 .8459948 1.5 5
trunk 74 13.75676 4.277404 5 23
weight 74 3019.459 777.1936 1760 4840
length 74 187.9324 22.26634 142 233
turn 74 39.64865 4.399354 31 51
displacement 74 197.2973 91.83722 79 425
gear_ratio 74 3.014865 .4562871 2.19 3.89

We can customize the appearance of the table using collect style. First, we omit the labels for the levels of Col. Then we add a border below Variable (Obs, Mean, etc.) and remove the border above it by setting the pattern to nil (or none). We also add a border below the results for trunk to be consistent with summarize that draws a separator every five variables. We can apply string formats to our results with the sformat() option; here %s refers to the results that are surrounded by two extra spaces before and after. We simply added some space to our results to get a wider layout to mimic the output of summarize. We don’t want the levels of Variable (Obs, Mean, etc.) to be bold, so we apply the SMCL directive text to format these cells. Here is our final table:

. collect style header Col, level(hide)

. collect style cell result[Variable], border(bottom) border(top, pattern(nil))

. collect style cell result[trunk], border(bottom)

. collect style cell, sformat("  %s  ")

. collect style cell result[Variable], smcl(text)

. collect preview

Variable Obs Mean Std. dev. Min Max
price 74 6165.257 2949.496 3291 15906
mpg 74 21.2973 5.785503 12 41
rep78 69 3.405797 .9899323 1 5
headroom 74 2.993243 .8459948 1.5 5
trunk 74 13.75676 4.277404 5 23
weight 74 3019.459 777.1936 1760 4840
length 74 187.9324 22.26634 142 233
turn 74 39.64865 4.399354 31 51
displacement 74 197.2973 91.83722 79 425
gear_ratio 74 3.014865 .4562871 2.19 3.89

If you have created your table layout using collect layout, then after formatting the table, it can be displayed again using collect preview. If we want to further format the numbers in cells, we could manipulate the local function display when collecting the results, such as"`:display %9.0gc r(min)'" to add comma format.

For our next example, suppose we want to create the following table:

Note that the rows are defined by categories of race and the columns are defined by the categories of sex. We can utilize the collect get command to create this table layout in Stata:

. collect clear

. collect get row1 = "47.57", tags(col[Male])

. collect get row1 = "52.43", tags(col[Female])

. collect get row2 = "46.04", tags(col[Male])

. collect get row2 = "53.96", tags(col[Female])

. collect get row3 = "51.50", tags(col[Male])

. collect get row3 = "48.50", tags(col[Female])

. collect layout (result) (col)

Collection: default
      Rows: result
   Columns: col
   Table 1: 3 x 2

Male Female
row1 47.57 52.43
row2 46.04 53.96
row3 51.50 48.50

First, we clear our previous collection of results. Then we create the result called row1 with the percent of males and females in the White category. We tag each result as belonging to the category Male or Female of the group col. Then we do the same for the categories Black and Other.

Below, we label our results with the category of race and the group size. To display the label “Sex”, we label col using collect label and we tell Stata to display the label for this header. The label “Sex” will be displayed above each level of col, so we tell Stata to horizontally center this duplicate header. Finally, we modify some borders, add a title, and preview our table. Here is the output:

. collect label levels result row1 "White (N=9065)"
>                              row2 "Black (N=1086)"
>                              row3 "Other (N=200)"

. collect label dim col "Sex"

. collect style header col, title(label)

. collect style column, dups(center)

. collect style cell cell_type[corner], border(right, pattern(nil))

. collect style cell col#cell_type[column-header], border(bottom, pattern(single))

. collect style cell result, border(right, pattern(nil))

. collect title "Table 1. Gender composition"

. collect style title, smcl(input)

. collect preview

Table 1. Gender composition
Sex
Male Female
White (N=9065) 47.57 52.43
Black (N=1086) 46.04 53.96
Other (N=200) 51.50 48.50

We have demonstrated how to create two tables from scratch. Now that you are familiar with using collect get to manually group your results into rows and columns of a table, you can create more complex tables.

The general syntax would be as follows:

collect get rows = “contents”, tags(columns)

. collect clear

. collect get row1 = "contents row1/col1", tags(col[first column])

. collect get row2 = "contents row2/col1", tags(col[first column])

. collect get row3 = "contents row3/col1", tags(col[first column])

. collect get row1 = "contents row1/col2", tags(col[second column])

. collect get row2 = "contents row2/col2", tags(col[second column])

. collect get row3 = "contents row3/col2", tags(col[second column])

. collect label levels result
>     row1 "first row" row2 "second row" row3 "third row", modify

. collect layout (result) (col)

Collection: default
      Rows: result
   Columns: col
   Table 1: 3 x 2

first column second column
first row contents row1/col1 contents row1/col2
second row contents row2/col1 contents row2/col2
third row contents row3/col1 contents row3/col2

You can use the code above as a template for manually creating your tables.