【问题标题】:Loading multiple .dta file加载多个 .dta 文件
【发布时间】:2017-05-06 19:16:12
【问题描述】:

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

我的 .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)

有谁知道如何避免使用循环并缩短我的代码?

【问题讨论】:

    标签: r


    【解决方案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") 
    

    【讨论】:

      【解决方案2】:

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

      1. 加载foreign 包:

        library(foreign) # or alternatively: library(haven)
        
      2. 创建文件名列表

        file.list <- list.files(path="E:/Folder", pattern='*.dat', full.names = TRUE)
        
      3. 确定要读取的文件(注意:您必须检查这些文件在substr 中的位置是否正确,这是我的估计)

        vec <- as.integer(substr(file.list,13,16))
        file.list2 <- file.list[vec==max(vec)]
        
      4. 读取文件

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

        names(df.list) <- gsub("E:/Folder","",names(df.list))
        
      6. 将数据框绑定到一个 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")
        

      现在您有了一个带有标识不同原始文件的 id 列的 data.frame。

      【讨论】:

        【解决方案3】:

        我会更改此任务的工作目录... 那么这是否符合您的要求?

        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)
        

        【讨论】:

        • 感谢 @Alias 提供的代码。它工作得很好。但是,您知道如何转换数据框中的“文件”吗?
        • @DavidMarguerit,如果您读入的文件包含向量或数据帧,那么您可以这样做:mydataframe=data.frame(files)。这个统一数据框的列名将与原始列名相同,但您将能够分辨出哪个列来自哪个文件,因为列名不仅包含原始列名,还包含它们来自的向量/数据框。因此,在统一数据框中,列名将具有以下结构: origin-name.column-name 。这种自动命名需要对列表组件进行命名。
        猜你喜欢
        • 1970-01-01
        • 2017-01-17
        • 2017-11-14
        • 1970-01-01
        • 1970-01-01
        • 2013-12-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多