Динамически создать новую переменную, затем вызвать эту переменную в цикле в R - PullRequest
0 голосов
/ 16 октября 2019

У меня есть цикл, который читает набор файлов, назначая имя каждого объекта динамически, используя имя файла. Каждый файл называется «timeseries_», а затем год.

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))
}

После чтения в каждом файле я хочу, чтобы цикл сохранял объект в файл .rda, но у меня возникают проблемы со ссылкой напеременная, которая была только что создана. Когда я использую as.name(), я получаю сообщение об ошибке:

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

Есть ли другой способ ссылки на только что созданную переменную?

1 Ответ

3 голосов
/ 16 октября 2019

Согласно странице справки ?save, функция сохранения также может принимать имя переменной в виде строки через параметр list=. Попробуйте что-то вроде этого

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")
}

Кроме того, если вы просто сохраняете одну переменную в файл, рассмотрите возможность использования saveRDS. Это позволит вам избежать неловкого назначения, если вам не понадобятся эти переменные позже.

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")
}

И вы прочитаете базу данных с помощью readRDS

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...