我有一个包含一堆. csv文件名称的数据框架。看起来它是如何在下面的代码片段:
我要做的是将这些。csv转换为附加每个结果的数据帧。我要做的是根据文件名创建三个不同的数据框架:
- 创建一个数据帧,其中包含文件名为
-callers-
的。csv文件的所有结果 - 创建一个数据帧,其中包含来自。csv文件的所有结果,文件名中包含
-results
- 创建一个数据帧,所有结果来自。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")
但我想做的是:
使用
s3read_using
函数迭代Key
下的所有.csv文件放在三个独立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_rows
和data.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)