Column Selection

Many Great Tables methods accept a columns= argument for targeting specific columns. Rather than limiting you to a simple list of column names, the package supports a flexible selection system that includes positional indexing, pattern-matching functions, and Polars selectors. This page demonstrates each of these approaches.

As your table-building code grows, hardcoding column names becomes fragile. If a column is renamed or added upstream, your table code breaks silently or raises an error. Pattern-based selection (whether through functions or Polars selectors) makes your code more resilient to upstream changes and more expressive about intent. Instead of listing every column by name, you can declare what kind of columns you want (e.g., all numeric columns, all columns starting with a prefix), and the selection adapts automatically as the data evolves.

Selection Options

The columns= argument for methods like tab_spanner(), cols_move(), and tab_style() allows a range of options for selecting columns.

The simplest approach is just a list of strings with the exact column names. However, we can specify columns using any of the following:

  • a single string column name.
  • an integer for the column’s position.
  • a list of strings or integers.
  • a Polars selector.
  • a function that takes a string and returns True or False.
from great_tables import GT
from great_tables.data import exibble

lil_exibble = exibble[["num", "char", "fctr", "date", "time"]].head(4)
gt_ex = GT(lil_exibble)

gt_ex
num char fctr date time
0.1111 apricot one 2015-01-15 13:35
2.222 banana two 2015-02-15 14:40
33.33 coconut three 2015-03-15 15:45
444.4 durian four 2015-04-15 16:50

This five-column table will serve as the basis for demonstrating each selection approach.

Using integers

We can use a list of strings or integers to select columns by name or position, respectively.

gt_ex.cols_move_to_start(columns=["date", 1, -1])
date char time num fctr
2015-01-15 apricot 13:35 0.1111 one
2015-02-15 banana 14:40 2.222 two
2015-03-15 coconut 15:45 33.33 three
2015-04-15 durian 16:50 444.4 four

Note the code above moved the following columns:

  • The string "date" matched the column of the same name.
  • The integer 1 matched the second column (this is similar to list indexing).
  • The integer -1 matched the last column.

Moreover, the order of the list defines the order of selected columns. In this case, "data" was the first entry, so it’s the very first column in the new table.

Using Polars selectors

When using a Polars DataFrame, you can select columns using Polars selectors. The example below uses Polars selectors to move all columns that start with "c" or "f" to the start of the table.

import polars as pl
import polars.selectors as cs

pl_df = pl.from_pandas(lil_exibble)

GT(pl_df).cols_move_to_start(columns=cs.starts_with("c") | cs.starts_with("f"))
char fctr num date time
apricot one 0.1111 2015-01-15 13:35
banana two 2.222 2015-02-15 14:40
coconut three 33.33 2015-03-15 15:45
durian four 444.4 2015-04-15 16:50

In general, selection should match the behaviors of the Polars DataFrame.select() method.

pl_df.select(cs.starts_with("c") | cs.starts_with("f")).columns
['char', 'fctr']

See the Selectors page in the polars docs for more information on this.

Using functions

A function can be used to select columns. It should take a column name as a string and return True or False.

gt_ex.cols_move_to_start(columns=lambda x: "c" in x)
char fctr num date time
apricot one 0.1111 2015-01-15 13:35
banana two 2.222 2015-02-15 14:40
coconut three 33.33 2015-03-15 15:45
durian four 444.4 2015-04-15 16:50

To summarize when to reach for each approach: use a plain list of names when you know exactly which columns you want and the list is short. Use Polars selectors when you want to match by dtype, prefix, suffix, or other structural properties of the columns. Use a function when you need custom logic that doesn’t fit neatly into a selector (e.g., matching against an external list or applying a complex naming convention rule).

These selection methods work consistently across all Great Tables methods that accept a columns= argument. Whether you prefer explicit column names, positional indexing, Polars selectors, or custom functions, you can choose the approach that best fits your workflow and data.