我有一个包含超过500个.dta文件的文件夹。我想将一些文件加载到一个R对象中。
我的.dta文件的通用名称由四部分组成:'两个字母/四个数字/ y / .dta'。例如,名称可以是'de2015y.dta'或'fr2008y.dta'。只有与两个字母和四个数字对应的部分才会在.dta文件中发生变化。
我编写了一个有效的代码,但我对此并不满意。我想避免使用循环并缩短它。
我的代码是:
asadmin
有谁知道如何避免使用循环并缩短我的代码?
答案 0 :(得分:1)
您也可以使用purrr
完成任务。
首先为您要加载的所有文件创建一个命名向量(据我了解您的问题,您只需要2015年的所有文件)。 setNames()
部分仅在您想要数据框中的ID变量并且尚未包含在.dta文件中时才是必需的。
之后,只需使用map_df()
读取所有文件并返回数据框。指定.id
是可选的,会生成ID列,其值的值基于in_files
的名称。
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")
答案 1 :(得分:0)
我会更改此任务的工作目录... 那么这会做你要求的吗?
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)
答案 2 :(得分:0)
以下步骤可为您提供所需内容:
加载foreign
包:
library(foreign) # or alternatively: library(haven)
创建文件名列表
file.list <- list.files(path="E:/Folder", pattern='*.dat', full.names = TRUE)
确定要读取的文件(注意:您必须检查这些文件在substr
中的位置是否正确,这是我方的估算值)
vec <- as.integer(substr(file.list,13,16))
file.list2 <- file.list[vec==max(vec)]
阅读文件
df.list <- sapply(file.list2, read.dta, simplify=FALSE)
从列表名中删除路径
names(df.list) <- gsub("E:/Folder","",names(df.list))
将数据帧绑定在一个data.frame / data.table中,并创建一个id-column
library(data.table)
df <- rbindlist(df.list, idcol = "id")
# or with 'dplyr'
library(dplyr)
df <- bind_rows(df.list, .id = "id")
现在你有一个data.frame,其id-column标识了不同的原始文件。