R 加载多个.dta文件

R 加载多个.dta文件,r,R,我有一个包含500多个.dta文件的文件夹。我想将其中一些文件加载到单个R对象中 My.dta文件的通用名称由四部分组成:“两个字母/四个数字/y/.dta”。例如,名称可以是“de2015y.dta”或“fr2008y.dta”。在.dta文件中,只有与两个字母和四个数字对应的部分会发生更改 我已经写了一段代码,但我并不满意。我希望避免使用循环并缩短它 我的代码是: # Select the .dta files I want to load #........................

我有一个包含500多个.dta文件的文件夹。我想将其中一些文件加载到单个R对象中

My.dta文件的通用名称由四部分组成:“两个字母/四个数字/y/.dta”。例如,名称可以是“de2015y.dta”或“fr2008y.dta”。在.dta文件中,只有与两个字母和四个数字对应的部分会发生更改

我已经写了一段代码,但我并不满意。我希望避免使用循环并缩短它

我的代码是:

# Select the .dta files I want to load
#.....................................

name <- list.files(path="E:/Folder")  # names of the .dta files in the folder
db <- as.data.frame(name)
db$year <- substr(db$name, 3, 6)
db <- subset (db, year == max(db$year))  # keep last year available
db$country <- substr(db$name, 1, 2)
list.name <- as.list(db$country)


# Loading all the .dta files in the Global environment
#..................................................

for(i in c(list.name)){
  obj_name <- paste(i, '2015y', sep='')
  file_name <- file.path('E:/Folder',paste(obj_name,'dta', sep ='.'))
  input <- read.dta13(file_name)
  assign(obj_name, value = input)
}


# Merge the files into a single object
#..................................................

df2015 <- rbind (at2015y, be2015y, bg2015y, ch2015y, cy2015y, cz2015y, dk2015y, ee2015y, ee2015y, es2015y, fi2015y,
              fr2015y, gr2015y, hr2015y, hu2015y, ie2015y, is2015y, it2015y, lt2015y, lu2015y, lv2015y, mt2015y,
              nl2015y, no2015y, pl2015y, pl2015y, pt2015y, ro2015y, se2015y, si2015y, sk2015y, uk2015y)

有人知道如何避免使用循环和缩短代码吗?

我会更改此任务的工作目录。。。 那么这能满足你的要求吗

setwd("C:/.../yourfiles")

# get file names where year equals "2015"
name=list.files(pattern="*.dta")
name=name[substr(name,3,6)=="2015"]

# read in the files in a list
files=lapply(name,foreign::read.dta)

# remove ".dta" from file names and
# give the file contents in the list their name
names(files)=lapply(name,function(x) substr(x, 1, nchar(x)-4))
#or alternatively
names(files)=as.list(substr(name,1,nchar(name)-4))

# optional: put all file contents into one data-frame
#(data-frames (vectors) need to have the same row counts (lengths) for this last step to work)
mydatafrm = data.frame(files)

以下步骤应满足您的需求:

加载外部包:

创建文件名列表

file.list <- list.files(path="E:/Folder", pattern='*.dat', full.names = TRUE)
读文件

df.list <- sapply(file.list2, read.dta, simplify=FALSE)
从列表名中删除路径

names(df.list) <- gsub("E:/Folder","",names(df.list))
将dataframes绑定到一个data.frame/data.table中,并创建一个id列

library(data.table)
df <- rbindlist(df.list, idcol = "id")

# or with 'dplyr'
library(dplyr)
df <- bind_rows(df.list, .id = "id")
现在您有了一个data.frame,其中包含一个标识不同原始文件的id列。

您还可以使用purrr执行任务

首先创建一个命名向量,包含您要加载的所有文件。我理解您的问题,您只需要2015年的所有文件。setNames部分仅在数据帧中需要ID变量且该变量尚未包含在.dta文件中时才有必要

之后,只需使用map_df读取所有文件并返回一个数据帧。指定.id是可选的,它会生成一个id列,其值基于in_文件的名称


谢谢@Alias提供您的代码。它工作得很好。但是,您知道如何转换数据帧中的文件吗?@DavidMarguerit,如果读入的文件包含向量或数据帧,则您可以执行以下操作:mydataframe=data.framefiles。此统一数据框的列名将与原始列名相同,但您将能够知道哪个列来自哪个文件,因为列名不仅包括原始列名,还包括它们来自的向量/数据框的名称。因此,在统一数据框架中,列名将具有以下结构:origin-name.column-name。这种自动命名要求对列表组件进行命名。
names(df.list) <- gsub("E:/Folder","",names(df.list))
library(data.table)
df <- rbindlist(df.list, idcol = "id")

# or with 'dplyr'
library(dplyr)
df <- bind_rows(df.list, .id = "id")
library(purrr)
library(haven)

in_files <- list.files(path="E:/Folder", pattern = "2015y", full.names = TRUE)
in_files <- setNames(in_files, in_files)

df2015 <- map_df(in_files, read_dta, .id = "id")