tibble() constructs a data frame. It is used like base::data.frame(), but with a couple notable differences:

  • The returned data frame has the class tbl_df, in addition to data.frame. This allows so-called "tibbles" to exhibit some special behaviour, such as enhanced printing. Tibbles are fully described in tbl_df.

  • tibble() is much lazier than base::data.frame() in terms of transforming the user's input. Character vectors are not coerced to factor. List-columns are expressly anticipated and do not require special tricks. Column names are not modified.

  • tibble() builds columns sequentially. When defining a column, you can refer to columns created earlier in the call. Only columns of length one are recycled.

tibble(..., .rows = NULL, .name_repair = c("check_unique", "unique",
  "universal", "minimal"))

Arguments

...

A set of name-value pairs. Arguments are evaluated sequentially, so you can refer to previously created elements. These arguments are processed with rlang::quos() and support unquote via !! and unquote-splice via !!!. Use := to create columns that start with a dot.

.rows

The number of rows, useful to create a 0-column tibble or just as an additional check.

.name_repair

Treatment of problematic column names:

  • "minimal": No name repair or checks, beyond basic existence,

  • "unique": Make sure names are unique and not empty,

  • "check_unique": (default value), no name repair, but check they are unique,

  • "universal": Make the names unique and syntactic

  • a function: apply custom name repair (e.g., .name_repair = make.names for names in the style of base R).

  • A purrr-style anonymous function, see rlang::as_function()

This argument is passed on as repair to vctrs::vec_as_names(). See there for more details on these terms and the strategies used to enforce them.

Value

A tibble, which is a colloquial term for an object of class tbl_df. A tbl_df object is also a data frame, i.e. it has class data.frame.

See also

Use as_tibble() to turn an existing object into a tibble. Use enframe() to convert a named vector into a tibble. Name repair is detailed in vctrs::vec_as_names(). rlang::list2() provides more details on tidy dots semantics, i.e. exactly how quasiquotation works for the ... argument.

Examples

# Unnamed arguments are named with their expression: a <- 1:5 tibble(a, a * 2)
#> # A tibble: 5 x 2 #> a `a * 2` #> <int> <dbl> #> 1 1 2 #> 2 2 4 #> 3 3 6 #> 4 4 8 #> 5 5 10
# Scalars (vectors of length one) are recycled: tibble(a, b = a * 2, c = 1)
#> # A tibble: 5 x 3 #> a b c #> <int> <dbl> <dbl> #> 1 1 2 1 #> 2 2 4 1 #> 3 3 6 1 #> 4 4 8 1 #> 5 5 10 1
# Columns are available in subsequent expressions: tibble(x = runif(10), y = x * 2)
#> # A tibble: 10 x 2 #> x y #> <dbl> <dbl> #> 1 0.579 1.16 #> 2 0.898 1.80 #> 3 0.344 0.689 #> 4 0.761 1.52 #> 5 0.731 1.46 #> 6 0.852 1.70 #> 7 0.976 1.95 #> 8 0.113 0.226 #> 9 0.970 1.94 #> 10 0.648 1.30
# tibble() never coerces its inputs, str(tibble(letters))
#> Classes ‘tbl_df’, ‘tbl’ and 'data.frame': 26 obs. of 1 variable: #> $ letters: chr "a" "b" "c" "d" ...
str(tibble(x = list(diag(1), diag(2))))
#> Classes ‘tbl_df’, ‘tbl’ and 'data.frame': 2 obs. of 1 variable: #> $ x:List of 2 #> ..$ : num [1, 1] 1 #> ..$ : num [1:2, 1:2] 1 0 0 1
# or munges column names (unless requested), tibble(`a + b` = 1:5)
#> # A tibble: 5 x 1 #> `a + b` #> <int> #> 1 1 #> 2 2 #> 3 3 #> 4 4 #> 5 5
# but it forces you to take charge of names, if they need repair: try(tibble(x = 1, x = 2))
#> Error : Column name `x` must not be duplicated. #> Use .name_repair to specify repair. #> Backtrace: #> █ #> 1. ├─base::tryCatch(...) #> 2. │ └─base:::tryCatchList(expr, classes, parentenv, handlers) #> 3. │ ├─base:::tryCatchOne(...) #> 4. │ │ └─base:::doTryCatch(return(expr), name, parentenv, handler) #> 5. │ └─base:::tryCatchList(expr, names[-nh], parentenv, handlers[-nh]) #> 6. │ └─base:::tryCatchOne(expr, names, parentenv, handlers[[1L]]) #> 7. │ └─base:::doTryCatch(return(expr), name, parentenv, handler) #> 8. ├─base::withCallingHandlers(...) #> 9. ├─base::saveRDS(...) #> 10. ├─base::do.call(...) #> 11. ├─(function (what, args, quote = FALSE, envir = parent.frame()) ... #> 12. └─(function (..., crayon_enabled, crayon_colors, pkgdown_internet) ... #> 13. └─pkgdown::build_site(...) #> 14. └─pkgdown:::build_site_local(...) #> 15. └─pkgdown::build_reference(...) #> 16. └─purrr::map(...) #> 17. └─pkgdown:::.f(.x[[i]], ...) #> 18. └─pkgdown:::data_reference_topic(...) #> 19. └─pkgdown:::run_examples(...) #> 20. └─pkgdown:::highlight_examples(code, topic, env = env) #> 21. └─evaluate::evaluate(x, child_env(env), new_device = TRUE) #> 22. └─evaluate:::evaluate_call(...) #> 23. ├─evaluate:::timing_fn(...) #> 24. ├─evaluate:::handle(...) #> 25. │ └─base::try(f, silent = TRUE) #> 26. │ └─base::tryCatch(...) #> 27. │ └─base:::tryCatchList(expr, classes, parentenv, handlers) #> 28. │ └─base:::tryCatchOne(expr, names, parentenv, handlers[[1L]]) #> 29. │ └─base:::doTryCatch(return(expr), name, parentenv, handler) #> 30. ├─base::withCallingHandlers(...) #> 31. ├─base::withVisible(eval(expr, envir, enclos)) #> 32. └─base::eval(expr, envir, enclos) #> 33. └─base::eval(expr, envir, enclos) #> 34. ├─base::try(tibble(x = 1, x = 2)) #> 35. │ └─base::tryCatch(...) #> 36. │ └─base:::tryCatchList(expr, classes, parentenv, handlers) #> 37. │ └─base:::tryCatchOne(expr, names, parentenv, handlers[[1L]]) #> 38. │ └─base:::doTryCatch(return(expr), name, parentenv, handler) #> 39. └─tibble::tibble(x = 1, x = 2) #> 40. └─tibble:::lst_to_tibble(xlq$output, .rows, .name_repair, lengths = xlq$lengths) #> 41. └─tibble:::set_repaired_names(x, .name_repair) #> 42. ├─rlang::set_names(...) #> 43. │ └─rlang:::set_names_impl(x, x, nm, ...) #> 44. │ └─rlang::is_function(nm) #> 45. │ └─rlang::is_closure(x) #> 46. └─tibble:::repaired_names(...) #> 47. ├─base::tryCatch(...) #> 48. │ └─base:::tryCatchList(expr, classes, parentenv, handlers) #> 49. │ ├─base:::tryCatchOne(...) #> 50. │ │ └─base:::doTryCatch(return(expr), name, parentenv, handler) #> 51. │ └─base:::tryCatchList(expr, names[-nh], parentenv, handlers[-nh]) #> 52. │ ├─base:::tryCatchOne(...) #> 53. │ │ └─base:::doTryCatch(return(expr), name, parentenv, handler) #> 54. │ └─base:::tryCatchList(expr, names[-nh], parentenv, handlers[-nh]) #> 55. │ └─base:::tryCatchOne(expr, names, parentenv, handlers[[1L]]) #> 56. │ └─base:::doTryCatch(return(expr), name, parentenv, handler) #> 57. └─vctrs::vec_as_names(name, repair = .name_repair, quiet = quiet) #> 58. └─vctrs:::validate_unique(names) #> 59. └─vctrs:::stop_names_must_be_unique(which(duplicated(names))) #> 60. └─vctrs:::stop_names(...) #> 61. └─vctrs:::stop_vctrs(...)
tibble(x = 1, x = 2, .name_repair = "unique")
#> New names: #> * x -> x...1 #> * x -> x...2
#> # A tibble: 1 x 2 #> x...1 x...2 #> <dbl> <dbl> #> 1 1 2
tibble(x = 1, x = 2, .name_repair = "minimal")
#> # A tibble: 1 x 2 #> x x #> <dbl> <dbl> #> 1 1 2
## By default, non-syntactic names are allowed, df <- tibble(`a 1` = 1, `a 2` = 2) ## because you can still index by name: df[["a 1"]]
#> [1] 1
df$`a 1`
#> [1] 1
with(df, `a 1`)
#> [1] 1
## Syntactic names are easier to work with, though, and you can request them: df <- tibble(`a 1` = 1, `a 2` = 2, .name_repair = "universal")
#> New names: #> * `a 1` -> a.1 #> * `a 2` -> a.2
df$a.1
#> [1] 1
## You can specify your own name repair function: tibble(x = 1, x = 2, .name_repair = make.unique)
#> New names: #> * x -> x.1
#> # A tibble: 1 x 2 #> x x.1 #> <dbl> <dbl> #> 1 1 2
fix_names <- function(x) gsub("\\s+", "_", x) tibble(`year 1` = 1, `year 2` = 2, .name_repair = fix_names)
#> New names: #> * `year 1` -> year_1 #> * `year 2` -> year_2
#> # A tibble: 1 x 2 #> year_1 year_2 #> <dbl> <dbl> #> 1 1 2
## purrr-style anonymous functions and constants ## are also supported tibble(x = 1, x = 2, .name_repair = ~ make.names(., unique = TRUE))
#> New names: #> * x -> x.1
#> # A tibble: 1 x 2 #> x x.1 #> <dbl> <dbl> #> 1 1 2
tibble(x = 1, x = 2, .name_repair = ~ c("a", "b"))
#> New names: #> * x -> a #> * x -> b
#> # A tibble: 1 x 2 #> a b #> <dbl> <dbl> #> 1 1 2
# Tibbles can contain columns that are tibbles or matrices # if the number of rows is consistent: tibble( a = 1:3, b = tibble( c = 4:6, d = 7:9 ), e = tibble( f = tibble( g = letters[1:3] ) ) )
#> # A tibble: 3 x 3 #> a b$c $d e$f$g #> <int> <int> <int> <chr> #> 1 1 4 7 a #> 2 2 5 8 b #> 3 3 6 9 c
tibble( a = 1:4, b = diag(4), c = cov(iris[1:4]) )
#> # A tibble: 4 x 3 #> a b[,1] [,2] [,3] [,4] c[,"Sepal.Lengt… [,"Sepal.Width"] #> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> #> 1 1 1 0 0 0 0.686 -0.0424 #> 2 2 0 1 0 0 -0.0424 0.190 #> 3 3 0 0 1 0 1.27 -0.330 #> 4 4 0 0 0 1 0.516 -0.122 #> # … with 2 more variables: [,"Petal.Length"] <dbl>, [,"Petal.Width"] <dbl>
# data can not contain POSIXlt columns, or tibbles or matrices # with inconsistent number of rows: try(tibble(y = strptime("2000/01/01", "%x")))
#> # A tibble: 1 x 1 #> y #> <dttm> #> 1 NA
try(tibble(a = 1:3, b = tibble(c = 4:7)))
#> Error : Tibble columns must have consistent lengths, only values of length one are recycled: #> * Length 3: Column `a` #> * Length 4: Column `b` #> Backtrace: #> █ #> 1. ├─base::tryCatch(...) #> 2. │ └─base:::tryCatchList(expr, classes, parentenv, handlers) #> 3. │ ├─base:::tryCatchOne(...) #> 4. │ │ └─base:::doTryCatch(return(expr), name, parentenv, handler) #> 5. │ └─base:::tryCatchList(expr, names[-nh], parentenv, handlers[-nh]) #> 6. │ └─base:::tryCatchOne(expr, names, parentenv, handlers[[1L]]) #> 7. │ └─base:::doTryCatch(return(expr), name, parentenv, handler) #> 8. ├─base::withCallingHandlers(...) #> 9. ├─base::saveRDS(...) #> 10. ├─base::do.call(...) #> 11. ├─(function (what, args, quote = FALSE, envir = parent.frame()) ... #> 12. └─(function (..., crayon_enabled, crayon_colors, pkgdown_internet) ... #> 13. └─pkgdown::build_site(...) #> 14. └─pkgdown:::build_site_local(...) #> 15. └─pkgdown::build_reference(...) #> 16. └─purrr::map(...) #> 17. └─pkgdown:::.f(.x[[i]], ...) #> 18. └─pkgdown:::data_reference_topic(...) #> 19. └─pkgdown:::run_examples(...) #> 20. └─pkgdown:::highlight_examples(code, topic, env = env) #> 21. └─evaluate::evaluate(x, child_env(env), new_device = TRUE) #> 22. └─evaluate:::evaluate_call(...) #> 23. ├─evaluate:::timing_fn(...) #> 24. ├─evaluate:::handle(...) #> 25. │ └─base::try(f, silent = TRUE) #> 26. │ └─base::tryCatch(...) #> 27. │ └─base:::tryCatchList(expr, classes, parentenv, handlers) #> 28. │ └─base:::tryCatchOne(expr, names, parentenv, handlers[[1L]]) #> 29. │ └─base:::doTryCatch(return(expr), name, parentenv, handler) #> 30. ├─base::withCallingHandlers(...) #> 31. ├─base::withVisible(eval(expr, envir, enclos)) #> 32. └─base::eval(expr, envir, enclos) #> 33. └─base::eval(expr, envir, enclos) #> 34. ├─base::try(tibble(a = 1:3, b = tibble(c = 4:7))) #> 35. │ └─base::tryCatch(...) #> 36. │ └─base:::tryCatchList(expr, classes, parentenv, handlers) #> 37. │ └─base:::tryCatchOne(expr, names, parentenv, handlers[[1L]]) #> 38. │ └─base:::doTryCatch(return(expr), name, parentenv, handler) #> 39. └─tibble::tibble(a = 1:3, b = tibble(c = 4:7)) #> 40. └─tibble:::lst_to_tibble(xlq$output, .rows, .name_repair, lengths = xlq$lengths) #> 41. └─tibble:::recycle_columns(x, .rows, lengths)
# Use := to create columns with names that start with a dot: tibble(.rows = 3)
#> # A tibble: 3 x 0
tibble(.rows := 3)
#> # A tibble: 1 x 1 #> .rows #> <dbl> #> 1 3
# You can unquote an expression: x <- 3 tibble(x = 1, y = x)
#> # A tibble: 1 x 2 #> x y #> <dbl> <dbl> #> 1 1 1
tibble(x = 1, y = !!x)
#> # A tibble: 1 x 2 #> x y #> <dbl> <dbl> #> 1 1 3
# You can splice-unquote a list of quosures and expressions: tibble(!!!list(x = rlang::quo(1:10), y = quote(x * 2)))
#> # A tibble: 10 x 2 #> x y #> <int> <dbl> #> 1 1 2 #> 2 2 4 #> 3 3 6 #> 4 4 8 #> 5 5 10 #> 6 6 12 #> 7 7 14 #> 8 8 16 #> 9 9 18 #> 10 10 20