简体   繁体   中英

Dynamically create new variable then call that variable in a loop in R

I have a loop that reads in a set of files, assigning the name of each object dynamically using the file name. Each file is named "timeseries_" and then a year.

library(haven)
library(dplyr)
library(stringr)

files <- list.files(path="data-raw/timeseries", pattern="*.dta", full.names=TRUE, recursive=FALSE)
for(file in files){
  assign(paste0("timeseries_",str_extract(file, "([0-9]+)")), read_dta(file))
}

After reading in each file, I want the loop to save the object to an.rda file, but I'm having trouble referring to the variable that was just created. When I use as.name() I get an error:

files <- list.files(path="data-raw/timeseries", pattern="*.dta", full.names=TRUE, recursive=FALSE)
for(file in files){
  assign(paste0("timeseries_",str_extract(file, "([0-9]+)")), read_dta(file))
  save(as.name(paste0("timeseries_",str_extract(file, "([0-9]+)"))),
    file=paste0("data/pilot_",str_extract(file, "([0-9]+)"), ".rda"), compress="xz")
}

Error in save(as.name(paste0("timeseries_", str_extract(file, "([0-9]+)"))),  : 
  object ‘as.name(paste0("timeseries_", str_extract(file, "([0-9]+)")))’ not found

Is there a different way to refer to the just-created variable?

According to the ?save help page, the save function can also take the name of the variable as a string via the list= parameter. Try something like this

files <- list.files(path="data-raw/timeseries", pattern="*.dta", full.names=TRUE, recursive=FALSE)
for(file in files) {
  datayear <- str_extract(file, "([0-9]+)")
  varname <- paste0("timeseries_", datayear)
  filename <- paste0("data/pilot_", datayear, ".rda")
  assign(varname, read_dta(file))
  save(list=varname, file=filename, compress="xz")
}

Also, if you are just saving one variable to a file, consider using saveRDS instead. It would allow you to avoid the awkward assign if you don't need these variables later.

files <- list.files(path="data-raw/timeseries", pattern="*.dta", full.names=TRUE, recursive=FALSE)
for(file in files) {
  datayear <- str_extract(file, "([0-9]+)")
  varname <- paste0("timeseries_", datayear)
  filename <- paste0("data/pilot_", datayear, ".rds")
  dtadata <- read_dta(file)
  saveRDS(dtadata, file=filename, compress="xz")
}

And you'd read the data base in with readRDS

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM