rguides

tribble

tribble(...)

Description

tribble() builds a tibble by laying out data row by row, reading left to right, the opposite of tibble() which takes column vectors. It is designed for small tables of data where readability matters, such as lookup tables, configuration data, or examples in documentation.

The column names are declared first using the formula syntax (~name), and the actual values follow. This makes the structure immediately visible when you read the code.

tribble() is part of the tibble package, which provides the tbl_df class, a stricter, more predictable reimagining of data.frame.

Arguments

Name-value pairs specifying column names and data. Column names must use the formula syntax (~column_name) and must appear before the corresponding values.

tribble(
  ~name, ~age,
  "Alice", 29,
  "Bob", 34
)
# # A tibble: 2 × 2
#   name   age
#   <chr> <dbl>
# 1 Alice   29
# 2 Bob     34

The ... arguments are processed with rlang::list2(), which means they support tidyeval unquoting via !! and unquote-splice via !!!.

tribble vs tibble vs data.frame

The three functions create rectangular data in R but with different layouts and constraints:

Featuretribble()tibble()data.frame()
LayoutRow-by-rowColumn-by-columnColumn-by-column
Column referencesNot supportedSequential evaluationNo
List columnsAuto-detectedAuto-detectedNo
Row namesNoNoYes
Partial matchErrorsErrorsSilent NULL
Vector recyclingErrorsErrorsSilent warning
# tibble: columns evaluated sequentially
tibble(x = 1:3, y = x * 2)
# # A tibble: 3 × 2
#       x     y
#   <int> <dbl>
# 1     1     2
# 2     2     4
# 3     3     6

# tribble: no sequential references — use tribble for this data layout
tribble(
  ~x, ~y,
  1, 2,
  2, 4,
  3, 6
)
# # A tibble: 3 × 2
#       x     y
#   <int> <dbl>
# 1     1     2
# 2     2     4
# 3     3     6

The tibble() constructor evaluates columns sequentially, which means a column defined later can reference an earlier one. The tribble() constructor, by contrast, reads data in a row-wise layout that resembles a text table and does not support cross-column references within the same call.

List columns

If any cell in tribble contains a vector longer than one element, that column becomes a list column (type <list>):

tribble(
  ~label, ~values,
  "first", 1:3,
  "second", 4:6
)
# # A tibble: 2 × 2
#   label values
#   <chr> <list>
# 1 first   <int [3]>
# 2 second  <int [3]>

List columns are useful for storing ragged or hierarchical data. Access individual elements with purrr::map() or dplyr::pull() followed by indexing.

Type coercion

tribble() infers column types from the data you provide, the same way tibble() does. Characters stay character, numbers stay numeric. If you need a specific type, for example, storing a date string as a Date object, use dplyr::mutate() with across() after creation:

tribble(
  ~name, ~joined, ~score,
  "Alice", "2020-01-15", "88",
  "Bob", "2019-07-22", "72"
) |>
  dplyr::mutate(
    dplyr::across(joined, as.Date),
    dplyr::across(score, as.integer)
  )
# # A tibble: 2 × 3
#   name  joined    score
#   <chr> <date>    <int>
# 1 Alice 2020-01-15    88
# 2 Bob   2019-07-22    72

tribble() is designed for small, hand-typed datasets, test fixtures, lookup tables, configuration data. The column-formula syntax makes it easy to read and diff in version control compared to a data.frame() call with parallel vectors. However, tribble() scales poorly for more than a dozen rows: the alternating row pattern becomes hard to scan, and there is no syntax for naming the column types. For larger static datasets, consider reading from a CSV literal with readr::read_csv() and a here-string, which gives you explicit types and is more familiar to collaborators.

Column types in tribble() are inferred from the first non-NA value in each column. All values in a column must be coercible to that type; a 1L mixed with 1.5 promotes to double. If you need a specific type that differs from the inferred type (e.g., a column of all-NA that should be logical), use as_tibble() with explicit type arguments or add a mutate() step after tribble().

See also

  • filter(), filter rows of a tibble by condition
  • pivot_longer(), reshape data from wide to long format
  • rownames() — get or set row names of a data frame or tibble