Home  /  Resources & support  /  FAQs  /  Access and modify table layout using collect layout

How do I change a table’s layout using collect layout?

Title   Access and modify table layout using collect layout
Author Chris Cheng, StataCorp

Tables created by the collect suite and table, dtable, and etable commands in Stata are composed of tagged items. The arrangement of rows and columns is controlled by the collect layout command. Its syntax is as follows:

. collect layout (rows) (cols) (tabs)
. collect layout (dimension[level1 level2 …]) (dimension[level1 level2 …]) (dimension[level1 level2 …])

The first set of parentheses represents rows, the second set represents columns, and the third set is used when creating separate tables based on dimensions. The item (value) in each cell of the table is determined by the tags you specified in all sets of parentheses jointly.

Understanding how collect layout builds tables

To illustrate how items are tagged, let's consider two dimensions, dim1 and dim2 in the collection, each with two levels. If dim1 is in the row and dim2 in the column, item 1.2 is identified by the combination of tags dim1[level1] and dim2[level1].

. collect layout (dim1[level1]) (dim2[level1])

Collection: default
      Rows: dim1[level1]
   Columns: dim2[level1]
   Table 1: 1 x 1

level1
level1 1.2

collect layout identifies items by unique combinations. Here there is more than one level in the column:

. collect layout (dim1[level1]) (dim2[level1 level2])

Collection: default
      Rows: dim1[level1]
   Columns: dim2[level1 level2]
   Table 1: 1 x 2

level1 level2
level1 1.2 1.3

The new item 1.3 is tagged and identified by dim1[level1] in the row and dim2[level2] in the column. Similarly, with two levels in the row:

. collect layout (dim1[level1 level2]) (dim2[level1])

Collection: default
      Rows: dim1[level1 level2]
   Columns: dim2[level1]
   Table 1: 2 x 1

level1
level1 1.2
level2 1.4

For two levels in both rows and columns:

. collect layout (dim1[level1 level2]) (dim2[level1 level2])

Collection: default
      Rows: dim1[level1 level2]
   Columns: dim2[level1 level2]
   Table 1: 2 x 2

level1 level2
level1 1.2 1.3
level2 1.4 1.5

The above can be simplified by just typing collect layout (dim1) (dim2) if both dimensions consist of only two levels, level1 and level2. What if we put both dimensions in one set of parentheses with an interaction sign #? Then we get this:

. collect layout (dim1#dim2)

Collection: default
      Rows: dim1#dim2
   Table 1: 6 x 1

level1
level1 1.2
level2 1.3
level2
level1 1.4
level2 1.5
. collect layout (dim2#dim1) Collection: default Rows: dim2#dim1 Table 1: 6 x 1
level1
level1 1.2
level2 1.4
level2
level1 1.3
level2 1.5

The order of dimensions matters. The above commands are equivalent to the following:

. collect layout (dim1[level1 level2]#dim2[level1 level2])

. collect layout (dim2[level1 level2]#dim1[level1 level2])

The # sign means the second dimension is nested within each level of the first dimension. Thus, the above specifications imply the following:

. collect layout (dim1[level1]#dim2[level1] dim1[level1]#dim2[level2] dim1[level2]#dim2[level1]
     dim1[level2]#dim2[level2])

. collect layout (dim2[level1]#dim1[level1] dim2[level1]#dim1[level2] dim2[level2]#dim1[level1]
     dim2[level2]#dim1[level2])

For your information, the tags for all the items:

Item Tags
1.2 dim1[level1] dim2[level1]
1.3 dim1[level1] dim2[level2]
1.4 dim1[level2] dim2[level1]
1.5 dim1[level2] dim2[level2]

If you are interested in how the items are put into the collection initially, see below:

. collect clear

. collect get my_stat = "1.2", tags(dim1[level1] dim2[level1])

. collect get my_stat = "1.3", tags(dim1[level1] dim2[level2])

. collect get my_stat = "1.4", tags(dim1[level2] dim2[level1])

. collect get my_stat = "1.5", tags(dim1[level2] dim2[level2])

Refer to FAQ: How can I create table layouts from scratch by using collect get? to learn about the collect get prefix and command and to see how the above tables are built up.

Using collect layout to customize tables

Once grasping how tables are built, we can customize their layout by using collect layout on ones created by table, etable, and dtable. Let’s see an example for table.

. collect clear

. sysuse auto

. table (foreign), statistic(mean price mpg) statistic(sd price mpg)

Mean Standard deviation
Price Mileage (mpg) Price Mileage (mpg)
Car origin
Domestic 6072.423 19.82692 3097.104 4.743297
Foreign 6384.682 24.77273 2621.915 6.611187
Total 6165.257 21.2973 2949.496 5.785503

We can access its layout by typing

. collect layout

Collection: Table
      Rows: foreign
   Columns: result#var
   Table 1: 4 x 4

(table omitted)

In the layout, we see that Rows uses the dimension foreign, while result#var is placed in Columns. The layout was created by the table command when we had (foreign) in the first set of parentheses to be used in the rows and table assumed and placed result in the columns with var nested within, which is why we used the interaction notation #.

The underlying collect layout specification is

. collect layout (foreign) (result#var)

To see the levels of each dimension, we can use the collect levelsof command, for instance,

. collect levelsof foreign

Collection: Table
 Dimension: foreign
    Levels: 0 1 .m
. collect levelsof result

Collection: Table
 Dimension: result
    Levels: mean sd
. collect levelsof var

Collection: Table
 Dimension: var
    Levels: price mpg

The complete specification is

. collect layout (foreign[0 1 .m]) (result[mean sd]#var[price mpg])

Items saved in the collection and their tags are

Item Tags
6072.423 foreign[0] result[mean] var[price]
6384.682 foreign[1] result[mean] var[price]
6165.257 foreign[.m] result[mean] var[price]
19.82692 foreign[0] result[mean] var[mpg]
24.77273 foreign[1] result[mean] var[mpg]
21.2973 foreign[.m] result[mean] var[mpg]
3097.104 foreign[0] result[sd] var[price]
2621.915 foreign[1] result[sd] var[price]
2949.496 foreign[.m] result[sd] var[price]
4.743297 foreign[0] result[sd] var[mpg]
6.611187 foreign[1] result[sd] var[mpg]
5.785503 foreign[.m] result[sd] var[mpg]

Then we can modify the table layout, for example, by removing the total level (.m) of foreign being displayed, moving mpg before price, and obtaining the mean and standard deviation for each variable.

. collect layout (foreign[0 1])  (var[mpg price]#result)

Collection: Table
      Rows: foreign[0 1]
   Columns: var[mpg price]#result
   Table 1: 3 x 4

Mileage (mpg) Price
Mean Standard deviation Mean Standard deviation
Car origin
Domestic 19.82692 4.743297 6072.423 3097.104
Foreign 24.77273 6.611187 6384.682 2621.915

After changing the order of var and result, we nested the levels of the latter dimension within the former one. If you want to swap the rows and columns by having variables (mpg and price) in the rows and foreign in the columns, please see FAQ: How do you reshape a table? to learn more about transposing and reshaping tables.

Last, let’s see an example for the third set of parentheses. The previous layout was

. collect layout (foreign) (result#var)

If we move the var dimension to be in the third set, we get this:

. collect layout (foreign) (result) (var)

Collection: Table
      Rows: foreign
   Columns: result
    Tables: var
   Table 1: 4 x 2
   Table 2: 4 x 2

Price
Mean Standard deviation
Car origin
Domestic 6072.423 3097.104
Foreign 6384.682 2621.915
Total 6165.257 2949.496
Mileage (mpg)
Mean Standard deviation
Car origin
Domestic 19.82692 4.743297
Foreign 24.77273 6.611187
Total 21.2973 5.785503

As shown, there are two separate tables created, one for price and one for mpg.

The same logic can be applied to tables created by etable and dtable. Learn more about it in [TABLES] collect layout. It is also possible to manipulate table layout using the Tables Builder; see [TABLES] Tables Builder.