41

I have a vector of column names called tbl_colnames.

I would like to create a tibble with 0 rows and length(tbl_colnames) columns.

The best way I've found of doing this is...

tbl <- as_tibble(data.frame(matrix(nrow=0,ncol=length(tbl_colnames)))

and then I want to name the columns so...

colnames(tbl) <- tbl_colnames.

My question: Is there a more elegant way of doing this?

something like tbl <- tibble(colnames=tbl_colnames)

colorlace
  • 636
  • 2
  • 10
  • 17
  • 2
    tibble columns have data types. Are you trying to make all your columns number? Also, what do you plan to do with this empty tibble? You're not going to try to add rows to it, are you? Because that's very inefficient. Better to build your data by columns first. Some more context here would be helpful. – MrFlick Feb 16 '18 at 19:47
  • 1
    You don't need to wrap with data.frame. Just `as_tibble(matrix(.` – akrun Feb 16 '18 at 19:50
  • Well I have a list of 5 lists and I want to rowbind them all together into one tibble. The idea was to start with an empty tibble and loop through the list rowbinding them to the initialized tibble one-by-one. – colorlace Feb 20 '18 at 15:08

6 Answers6

37
my_tibble <- tibble(
  var_name_1 = numeric(),
  var_name_2 = numeric(),
  var_name_3 = numeric(),
  var_name_4 = numeric(),
  var_name_5 = numeric()
)

Haven't tried, but I guess it works too if instead of initiating numeric vectors of length 0 you do it with other classes (for example, character()).

This SO question explains how to do it with other R libraries.

According to this tidyverse issue, this won't be a feature for tribbles.

Daniel
  • 826
  • 1
  • 11
  • 20
  • 1
    Thanks. I was hoping to use the `tbl_colnames` vector directly when I asked this question, but it's true that this is one way to do it (if a bit cumbersome). In any case, it could be helpful for others seeking different ways to init tibbles. – colorlace Sep 03 '19 at 14:09
29

Since you want to combine a list of tibbles. You can just assign NULL to the variable and then bind_rows with other tibbles.

res = NULL
for(i in tibbleList)
   res = bind_rows(res,i)

However, a much efficient way to do this is

bind_rows(tibbleList) # combine all tibbles in the list
Tony416
  • 536
  • 6
  • 11
  • Thank you for your answer. It was a list of lists (not a list of tibbles), but this seems to work anyway! – colorlace Jun 06 '18 at 15:51
  • 5
    This answer is responsive to a comment that is only peripherally related the title of and question posted on this page. – Aren Cambre Oct 31 '19 at 02:38
20

For anyone still interested in an elegant way to create a 0-row tibble with column names given by a character vector tbl_colnames:

tbl_colnames %>% purrr::map_dfc(setNames, object = list(logical()))

or:

tbl_colnames %>% purrr::map_dfc(~tibble::tibble(!!.x := logical()))

or:

tbl_colnames %>% rlang::rep_named(list(logical())) %>% tibble::as_tibble()

This, of course, results in each column being of type logical.

Nik
  • 305
  • 2
  • 6
4

You could abuse readr::read_csv, which allow to read from string. You can control names and types, e.g.:

tbl_colnames <- c("one", "two", "three", "c4", "c5", "last")
read_csv("\n", col_names = tbl_colnames) # all character type
read_csv("\n", col_names = tbl_colnames, col_types = "lcniDT") # various types
Marek
  • 47,613
  • 13
  • 96
  • 119
1

I'm a bit late to the party, but for future readers:

as_tibble(matrix(nrow = 0, ncol = length(tbl_colnames)), .name_repair = ~ tbl_colnames)

.name_repair allows you to name you columns within the same function.

Daniël
  • 11
  • 2
0

The following command will create a tibble with 0 row and variables (columns) named with the contents of tbl_colnames

tbl <- tibble::tibble(!!!tbl_colnames, .rows = 0)

R Moore
  • 61
  • 1
  • 3