2017-10-01 1 views
0

Je souhaite lire un ensemble d'ensembles de données (par exemple * .dta) avec un préfixe spécifique et un modèle de nombre croissant dans l'environnement global, et les combiner dans une liste. (Dans ce cas particulier, ils sont tous de même dimension.)Comment lire plusieurs ensembles de données avec un modèle de préfixe spécifique dans un environnement global?

Traditionnellement code I:

library(foreign) # for reading *.dta files 

df_1 <- read.dta("df_1.dta") 
df_2 <- read.dta("df_2.dta") 
... 
df_n <- read.dta("df_n.dta") # note: consider 'n' being an arbitrary defined integer 

df_lst <- mget(ls(pattern = "df[0-9]")) # combine dfs into list 

Maintenant, je veux y arriver en une seule étape brève.

cette boucle I essayé qui ne fonctionne pas - le plus probable en raison de la définition d'une variable entre guillemets:

# initialize list 
df_lst <- list() 

# read and combine dfs into list 
i <- 0 
while(i < n) { 
    i = i + 1 
    df_[i] = read.dta("df_[i].dta") 
    c(df_lst, df[i]) 
} 

De plus je préfère préfèrent une fonction d'une boucle.

Comment puis-je atteindre mon objectif?

Répondre

1

Essayez d'utiliser rio:

rio::import_list(dir(pattern = "df[0-9]")) 

Ceci renvoie une liste des trames de données.

(D'une manière générale, il n'y a pas besoin d'importer des fichiers de données dans l'environnement mondial avant de les mettre dans une liste.)

divulgation complète: Je suis le responsable de Rio.

+0

Tout simplement génial! Comment puis-je définir le répertoire? Par exemple. 'rio :: import_list (dir (pattern =" data/df [0-9] "))' semble ne pas fonctionner. – jaySf

+0

(Lève "Erreur dans if (! Grepl ("^http. *: // ", fichier)) {: l'argument est de longueur zéro".) – jaySf

+1

Sont-ils dans un sous-répertoire? Ensuite, vous avez probablement besoin de quelque chose comme 'dir (" ./ data ", pattern =" df [0-9 ", full.names = TRUE)' Je suppose. Fondamentalement, cet argument de 'import_list()' devrait juste être un vecteur de chemins de fichiers relatifs ou absolus. – Thomas

1

pour la boucle, utilisez la pâte pour recréer le nom:

# initialize list 
df_lst <- list() 

# read and combine dfs into list 
i <- 0 
while(i < n) { 
    i = i + 1 
    df_[i] = read.dta(paste("df_[",i,"].dta",sep='')) 
    c(df_lst, df[i]) 
} 

et définir « n » (je suppose que vous l'avez fait, mais ne semble pas défini dans le texte)

acclamations

Fer

+0

Oui, 'n' est considéré comme défini, j'ai fait un commentaire sur mon code, merci! – jaySf

1

en utilisant assign() et do.call("list",...), vous pouvez le faire avec une fonction:

# list of filenames matching pattern 
fnames <- list.files(pattern = "df_[0-9].dta") 

# function to read, assign to global env, and return data 
dtafx <- function(i){ 
    df <- foreign::read.dta(fnames[i]) 
    assign(gsub(".dta", "", fnames[i]), df, envir = .GlobalEnv) 
    return(df) 
} 

# apply function to filenames, combining dfs into list 
df_lst <- do.call("list", sapply(seq_along(fnames), dtafx, simplify = F))