【问题标题】:How to read multiple large sas data files into R, filter rows and save subset datasets as .rds如何将多个大型 sas 数据文件读入 R,过滤行并将子集数据集保存为 .rds
【发布时间】:2019-10-15 21:35:56
【问题描述】:

我在一个文件夹中有 30 个 sas 文件(dataset1.sas7bdat 到 dataset30.sas7bdat,每个文件大约 10 GB),并且需要分析这些数据文件中的一部分行(字符变量 A 开始的所有行与 10)。 因此,我需要将每个 sas 文件读入 R,在变量 A 上使用 grep 过滤一个子集,然后将每个过滤后的数据集保存为 .rds 文件。 我正在尝试使用 list.files() 的 for 循环和 Haven 包来读取 sas 文件来实现这一点。为了避免内存不足,在子集被过滤并保存为 .rds 后,我需要在每次迭代中删除导入的数据集。

虽然不优雅也不令人满意,但我可以像这样手动硬编码 30 次,每次复制/粘贴并将后缀增加 1:

dt1 <- haven::read_sas("~/folder/dataset1.sas7bdat")
dt1 <- data.table::as.data.table(dt1)
dt1 <- dt1[grep("^10", A)]
saveRDS(dt1, "~/folder/subset1.rds")

dt2 <- haven::read_sas("~/folder/dataset2.sas7bdat")
dt2 <- data.table::as.data.table(dt2)
dt2 <- dt1[grep("^10", A)]
saveRDS(dt2, "~/folder/subset2.rds")
etc.

虽然以下 for 循环在技术上可以将文件读入内存,但由于大量内存不足,它永远不会完成,因此它不允许我过滤数据:

folder <- "~/folder/"
file_list <- list.files(path = folder, pattern = "^dataset")
for (i in 1:length(file_list)) {
 assign(file_list[i], Haven::read_sas(paste(folder, file_list[i], sep='')))
}

有没有办法 - 在循环中的每次迭代中 - 过滤数据集,删除未过滤的数据集并将子集保存在 .rds 文件中? 我似乎无法想出一种方法将其合并到我使用 assign() 函数的方法中。 有没有更好的方法来解决这个问题?

【问题讨论】:

    标签: r r-haven


    【解决方案1】:

    您可以通过在每次加载和过滤后清除内存来释放内存

    rm(list=ls())
    

    【讨论】:

    • 写出后为什么要清除整个全局环境,而不是只清除file_list[i]对象?
    【解决方案2】:

    我睡在上面,醒来后发现了一个可行的解决方案,该解决方案使用一个函数来完成工作,并使用一个循环来循环文件名。这也使我能够将输出保存在不同的文件夹中(我的原始数据文件夹是只读的):

    library(haven)
    library(data.table)
    fromFolder <- "~/folder_with_input_data/"
    toFolder <- "~/folder_with_output_data/"
    import_sas <- function(filename) {
    dt <- read_sas(paste(fromFolder, filename, sep=''), NULL)
    dt <- as.data.table(dt)
    dt <- dt[grep("^10", A)]
    saveRDS(dt, paste(toFolder,filename,'.rds.', sep =''), compress = FALSE)
    remove(dt)
    }
    
    file_list <- list.files(path = fromFolder, pattern="^dataset")
    for (filename in file_list) {
    import_sas(filename)
    }
    

    我还没有用完整的 30 个文件对此进行测试。我今晚会这样做。 如果我遇到问题,我会在明天发布更新。否则,这个问题可以在 48 小时内关闭。

    更新:它运行顺利,在大约 13 小时内完成了 297GB 的转换。我不认为可以对其进行优化以更快地完成任务;绝大多数计算时间都花在了打开 sas 文件上,我认为除了 Haven 之外,其他方式都无法做到这一点。除非有人有优化流程的想法,否则这个问题可以关闭。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-26
      • 2016-02-05
      • 2011-12-24
      • 1970-01-01
      • 2017-02-22
      • 2020-12-08
      • 2020-12-16
      • 1970-01-01
      相关资源
      最近更新 更多