Search code examples
rreadr

readr: Passing a string of column classes


I want to use readr::read_csv() to read several data sets.

I have a CSV with the description of each file that looks like this:

# A tibble: 5 x 8
  Object_Name File_Path      Column1   Column2   Column3   Column4 Column5 Column6
  <chr>       <chr>          <chr>     <chr>     <chr>     <chr>   <chr>   <chr>  
1 Object1     data/file1.csv character character character numeric numeric numeric
2 Object2     data/file2.csv character character character numeric NA      NA     
3 Object3     data/file3.csv character character numeric   NA      NA      NA     
4 Object4     data/file4.csv character numeric   numeric   numeric NA      NA     
5 Object5     data/file5.csv character numeric   numeric   NA      NA      NA    

What I wish if for something like this to work:

for (i in 1:nrow(list_of_files)) {

  obj_name <- list_of_files[i,]$Object_Name
  pth <- list_of_files[i,]$File_Path

  col_types <- as.character(list_of_files[i,3:8])
  col_types <- col_types[!is.na(col_types)]

  # This part doesnt work
  tab <- readr::read_csv(file = pth,
                         col_types = col_types)

  assign(obj_name,tab)

}

Usually the guessing works, but I need to make sure.

EDIT

Simplifying the questions, so maybe it's clearer.

To specify the columns types on read_csv, you need a cols() call.

This works:

> cols('c', 'n')
cols(
   = col_character(),
   = col_number()
)

This doesn't work:

> aa <- c('c','n')
> cols(aa)
Error in switch(x, `_` = , `-` = col_skip(), `?` = col_guess(), c = col_character(),  : 
  EXPR must be a length 1 vector

Because I'm iterating through a bunch of files, I need something that looks like the second example. I can save somewhere a string with the columns specifications, but how do I turn a string into a cols() object?


Solution

  • For you to obtain the second example, you can just use do.call:

    aa <- c('c','n')
    do.call(cols,as.list(aa))
    
    cols(
       = col_character(),
       = col_number()
    )