r语言 - 基于文件名迭代csv到不同的数据框架



我有一个包含一堆. csv文件名称的数据框架。看起来它是如何在下面的代码片段:

我要做的是将这些。csv转换为附加每个结果的数据帧。我要做的是根据文件名创建三个不同的数据框架:

  1. 创建一个数据帧,其中包含文件名为-callers-的。csv文件的所有结果
  2. 创建一个数据帧,其中包含来自。csv文件的所有结果,文件名中包含-results
  3. 创建一个数据帧,所有结果来自。csv文件,文件名中有-script_results-

实际将。csv文件转换为数据框的命令如下所示,如果我在下面的数据框中使用第一个。csv文件:

data <- aws.s3::s3read_using(read.csv, object = "s3://abc-testtalk/08182020-testpilot-arizona-results-08-18-2020--08-18-2020-168701001.csv")

但我想做的是:

  1. 使用s3read_using函数迭代Key下的所有.csv文件

  2. 放在三个独立dataframes基于文件名上面列出的

    Key
    08182020-testpilot-arizona-results-08-18-2020--08-18-2020-168701001.csv
    08182020-testpilot-arizona-results-08-18-2020--08-18-2020-606698088.csv
    08182020-testpilot-arizona-script_results-08-18-2020--08-18-2020-114004469.csv
    08182020-testpilot-arizona-script_results-08-18-2020--08-18-2020-450823767.csv
    08182020-testpilot-iowa-callers-08-18-2020-374839084.csv
    08182020-testpilot-maine-callers-08-18-2020-396935866.csv
    08182020-testpilot-maine-results-08-18-2020--08-18-2020-990912614.csv
    08182020-testpilot-maine-script_results-08-18-2020--08-18-2020-897037786.csv
    08182020-testpilot-michigan-callers-08-18-2020-367670258.csv
    08182020-testpilot-michigan-follow-ups-08-18-2020--08-18-2020-049435266.csv
    08182020-testpilot-michigan-results-08-18-2020--08-18-2020-544974900.csv
    08182020-testpilot-michigan-script_results-08-18-2020--08-18-2020-239089219.csv
    08182020-testpilot-nevada-callers-08-18-2020-782329503.csv
    08182020-testpilot-nevada-results-08-18-2020--08-18-2020-348644934.csv
    08182020-testpilot-nevada-script_results-08-18-2020--08-18-2020-517037762.csv
    08182020-testpilot-new-hampshire-callers-08-18-2020-134150800.csv
    08182020-testpilot-north-carolina-callers-08-18-2020-739838755.csv
    08182020-testpilot-pennsylvania-callers-08-18-2020-223839956.csv
    08182020-testpilot-pennsylvania-results-08-18-2020--08-18-2020-747438886.csv
    08182020-testpilot-pennsylvania-script_results-08-18-2020--08-18-2020-546894204.csv
    08182020-testpilot-virginia-callers-08-18-2020-027531377.csv
    08182020-testpilot-virginia-follow-ups-08-18-2020--08-18-2020-419338697.csv
    08182020-testpilot-virginia-results-08-18-2020--08-18-2020-193170030.csv
    

创建3个空数据框架。您可能还需要指定与要追加的每个文件的列名相匹配的列名:

results <- data.frame()
script_results <- data.frame()
callers <- data.frame()

然后遍历file_name,读入data对象。根据模式("-results-", "-script_results-")或"调用方产生绯闻;包含在每个文件的名称中,它将被附加到正确的数据帧:

for (file in file_name) {
data <- aws.s3::s3read_using(read.csv, object = paste0("s3://abc-testtalk/", file))

if (grepl(file, "-results-")) { results <- rbind(results, data)}
if (grepl(file, "-script_results-")) { script_results <- rbind(script_results, data)}
if (grepl(file, "-callers-")) { callers <- rbind(callers, data)}

}

作为@JohnFranchak推荐的map_dfr的替代方法(它可能工作得很好),我在注释中引用的方法看起来像这样:

alldat <- lapply(setNames(nm = dat$file_name),
function(obj) aws.s3::s3read_using(read.csv, object = obj))
callers <- do.call(rbind, alldat[grepl("-callers-", names(alldat))])
results <- do.call(rbind, alldat[grepl("-results-", names(alldat))])
script_results <- do.call(rbind, alldat[grepl("-script_results-", names(alldat))])
others <- do.call(rbind, alldat[!grepl("-(callers|results|script_results)-", names(alldat))])

do.call(rbind, ...)部分类似于dplyr::bind_rowsdata.table::rbindlist,因为它接受帧列表,结果是单个帧。一些差异:

  • do.call(rbind, ...)确实要求所有列以相同的顺序存在于所有帧中。在外部执行这一点并不困难(例如,添加缺失的列,重新排列),但这不是自动的。
  • data.table::rbindlist将抱怨相同的条件(缺少列或不同的顺序),但它有fill=use.names=参数需要设置TRUE
  • dplyr::bind_rows将填补和row-bind默认的名字,没有消息或警告。(我不同意默认的沉默总是好的,但它是最简单的。)

最后,我使用setNames(nm=..)仅仅是为每个对象分配文件名。这并不是严格必要的,因为我们仍然有dat$file_name,但我发现,对于两个单独的对象,意外更改(删除,追加或重新排序)其中一个而不是另一个是可行的,所以我更喜欢保持名称和对象(框架)完美地捆绑在一起。这两个调用在结果命名列表中相对相同:

lapply(setNames(nm = dat$file_name), ...)
sapply(dat$file_name, ..., simplify = FALSE)

最新更新