Reputation: 2763
I would like to create an empty data frame where the column names are coming from a character vector.
for example, if this was my vector:
vec <- letters[1:3]
I would like create an empty data frame like the following:
df <- tibble('a' = character(), 'b' = character(), 'c' = character())
however, I would like to iterate through the items in the vector to populate the dataframe names and not have to manually specify each one. In reality my vector has 40+ names.
I've tried the following by they don't work:
df <- tibble(vec[1:3])
df <- tibble(vec)
df <- tibble(for (i in 1:3){
vec[i]
})
Any help on this would be greatly appreciated!
Upvotes: 10
Views: 9814
Reputation: 50704
You could use read_csv
from readr
package, which could read from text vector.
First you need to paste
your vector and then read it:
readr::read_csv(I(paste(vec, collapse=",")), col_types = "c")
In pipeline:
vec %>%
paste(collapse = ",") %>% # makes "a,b,c"
I() %>% # needed for read_ to treat as string not a file
readr::read_csv(col_types = "c") # columns types as characters
Upvotes: 0
Reputation: 33498
Another variant of Adam's idea:
as_tibble(sapply(vec, \(x) character()))
# A tibble: 0 x 3
# ... with 3 variables: a <chr>, b <chr>, c <chr>
Upvotes: 3
Reputation: 46856
A variant on Adam's solution is to create a named list of appropriate types, e.g.,
n = length(vec)
tmpl = setNames(rep(list(character()), n), head(letters, n))
This reflects the underlying structure of a data.frame or tibble -- a named list of equal-length vectors. Then
as.data.frame(tmpl, stringsAsFactors = FALSE)
tibble::as_tibble(tmpl)
Upvotes: 1
Reputation:
You can create a named vector, vec
, where the first argument sets the type of column you want. The rep("", 3)
line says I want three character columns. Then the second argument is the vector of column names.
Use dplyr::bind_rows
to convert this into tibble with one row. Then [0, ]
selects zero rows, leaving it empty.
With this method, you can control the data type for each column easily.
library(dplyr)
vec <- setNames(rep("", 3), letters[1:3])
bind_rows(vec)[0, ]
# A tibble: 0 x 3
# ... with 3 variables: a <chr>, b <chr>, c <chr>
You can also use as_tibble
if you transpose the named vector. I guess I use bind_rows
because I usually have dplyr
loaded but not tibble
.
library(tibble)
vec <- setNames(rep("", 3), letters[1:3])
as_tibble(t(vec))[0, ]
# A tibble: 0 x 3
# ... with 3 variables: a <chr>, b <chr>, c <chr>
If you know all of the columns are of a single type (e.g., character), you can do something like this.
vec <- letters[1:3]
df <- bind_rows(setNames(rep("", length(vec)), vec))[0, ]
Upvotes: 5
Reputation: 6441
You can do
library(tibble)
tb <- as_tibble(matrix(nrow = 0, ncol = length(vec), dimnames = list(NULL, vec)))
tb
# A tibble: 0 x 3
# ... with 3 variables: a <lgl>, b <lgl>, c <lgl>
Upvotes: 3