I have an .RDS data file where all columns are strings. I want to convert each column of this data to an appropriate type. But I also want to save the column specifications to change some of them. I can get the specification of each column using spec() if I read a CSV file.
library(tidyverse)
library(lubridate)
df <- midwest %>%
slice(1:10) %>%
mutate(date1 = seq(ymd('2021-06-07'), ymd('2021-06-16'), by = '1 day'),
date2 = seq(as.Date('2021/6/7'), by = 'month', length.out = 10),
empty1 = NA, empty2 = NA, empty3 = NA, empty4 = NA,
empty11 = NA, empty21 = NA, empty31 = NA, empty41 = NA,
empty12 = NA, empty22 = NA, empty32 = NA, empty42 = NA,
empty13 = NA, empty23 = NA, empty33 = NA, empty43 = NA,
dt = date1 + seconds(row_number()-1),
time = format(dt, format = "%H:%M:%S")) %>%
mutate(across(everything(), as.character))
# A temporary file to hold the data
f <- file.path(tempdir(), "midwest10.csv")
write.csv(df, f, row.names = FALSE)
df3 <- read_csv(f, show_col_types = FALSE)
spec(df3) # <-- This works perfectly
#> cols(
#> PID = col_double(),
#> county = col_character(),
#> state = col_character(),
#> area = col_double(),
#> poptotal = col_double(),
#> popdensity = col_double(),
#> popwhite = col_double(),
#> popblack = col_double(),
#> popamerindian = col_double(),
#> popasian = col_double(),
#> popother = col_double(),
#> percwhite = col_double(),
#> percblack = col_double(),
#> percamerindan = col_double(),
#> percasian = col_double(),
#> percother = col_double(),
#> popadults = col_double(),
#> perchsd = col_double(),
#> percollege = col_double(),
#> percprof = col_double(),
#> poppovertyknown = col_double(),
#> percpovertyknown = col_double(),
#> percbelowpoverty = col_double(),
#> percchildbelowpovert = col_double(),
#> percadultpoverty = col_double(),
#> percelderlypoverty = col_double(),
#> inmetro = col_double(),
#> category = col_character(),
#> date1 = col_date(format = ""),
#> date2 = col_date(format = ""),
#> empty1 = col_logical(),
#> empty2 = col_logical(),
#> empty3 = col_logical(),
#> empty4 = col_logical(),
#> empty11 = col_logical(),
#> empty21 = col_logical(),
#> empty31 = col_logical(),
#> empty41 = col_logical(),
#> empty12 = col_logical(),
#> empty22 = col_logical(),
#> empty32 = col_logical(),
#> empty42 = col_logical(),
#> empty13 = col_logical(),
#> empty23 = col_logical(),
#> empty33 = col_logical(),
#> empty43 = col_logical(),
#> dt = col_datetime(format = ""),
#> time = col_time(format = "")
#> )
But I cannot get anything from the spec() function if the data is saved in an RDS file (or, more generally, a data set in the current environment). How can I make spec() work for data already in the working directory? Ideally, I don't want to write the RDS file to a CSV file and read it back via read_csv().
f <- file.path(tempdir(), "midwest10.RDS")
saveRDS(df, f)
df2 <- readRDS(f)
df2 <- type_convert(df2)
#>
#> -- Column specification --------------------------------------------------------
#> cols(
#> .default = col_double(),
#> county = col_character(),
#> state = col_character(),
#> category = col_character(),
#> # ... with 20 more columns
#> )
#> i Use `spec()` for the full column specifications.
spec(df2) # <--- Ideally, this returns column specifications instead of NULL
#> NULL