【发布时间】:2021-08-14 05:43:32
【问题描述】:
我的数据集的一个非常简化的示例:
HUC8 YEAR RO_MM
1: 10010001 1961 78.2
2: 10010001 1962 84.0
3: 10010001 1963 70.2
4: 10010001 1964 130.5
5: 10010001 1965 54.3
我在网上找到了这段代码,但不是完全符合我的要求:
#create a list of the files from your target directory
file_list <- list.files(path="~/Desktop/Rprojects")
#initiate a blank data frame, each iteration of the loop will append the data from the given file to this variable
allHUCS <- data.frame()
#I want to read each .csv from a folder named "Rprojects" on my desktop into one huge dataframe for further use.
for (i in 1:length(file_list)){
temp_data <- fread(file_list[i], stringsAsFactors = F)
allHUCS <- rbindlist(list(allHUCS, temp_data), use.names = T)
}
问题:我读到不应将 rbindlist 用于大型数据集:
“你永远不应该在循环中迭代 rbind:一开始性能可能还不错,但是每次调用 rbind 都会生成一个完整的数据副本,因此每次传递时要复制的总数据都会增加。它可怕地扩展。考虑 do.call(rbind.data.frame, file_list)。" – @r2evans
我知道这可能看起来很简单,但我不清楚如何使用他的指令。我会在最后一行写这个吗?
allHUCS <- do.call(rbind.data.frame(allHUCS, temp_data), use.names = T)
还是别的什么?在我的实际数据中,每个 .csv 有 2099 个对象和 3 个变量(但我只关心最后两个。)总数据框应该包含 47,000,000+ 个对象的 2 个变量。当我运行原始代码时,我得到了这些错误:
rbindlist(list(allHUCS, temp_data), use.names = T) 中的错误:第 2 项 有 2 列,与有 3 列的项目 1 不一致。填写 缺少的列使用 fill=TRUE。
另外:警告消息:1:在 fread(file_list[i], stringsAsFactors = F) : 检测到 1 个列名,但数据有 2 个 列(即无效文件)。为 第一列被猜测为行名或索引。采用 setnames() 如果这个猜测不正确,或者修复文件 写入创建文件的命令以创建有效文件。
2:在 fread(file_list[i], stringsAsFactors = F) 中:提前停止 第 20 行。预期 2 个字段,但找到 3。考虑 fill=TRUE 和 评论.char=。第一个丢弃的非空行: >
除了setnames() 的建议,我不明白别人告诉我什么。我知道它说它提前停止了,但我什至不知道如何查看整个数据集或判断它停止的位置。
我现在读到 rbindlist 和 rbind 是两个不同的东西,rbindlist 比 do.call(rbind, data) 快。但建议是 do.call(rbind.data.frame(allHUCS, temp_data)。哪个最快?
【问题讨论】:
-
你需要
do.call(rbind, lapply(file_list, fread)) -
或者,如果您已经在使用
data.table函数,只需执行rbindlist(lapply(file_list, fread))。您引用的 cmets 的全部要点是 R 中增长的对象可能效率低下。因此最好立即对孔对象执行任何操作,而不是在for loop中。您收到的错误/警告表明您正在阅读的所有文件可能没有相同的标题。为了安全起见,首先将所有内容都读入列表中,然后担心以后将它们绑定在一起,df_list <- lapply(fille_list, fread); lapply(df_list, colnames) #inspect output -
@JustinLandis 对它们的随机抽样显示它们是相同的:名为 HUC8、YEAR、RO_MM 的三列。所有 344,000 多个 csv 文件都是在同一操作中创建的。他们仍然有可能有不同的标题吗?另外,您能否解释一下
rbindlist(lapply(file_list, fread))将适合我的代码,而不是哪一行,或者它代替整个for循环?我真的很陌生。 -
这将替换整个循环。
lapply函数会将第二个参数(一个函数)应用于第一个参数的每个元素,并以列表的形式返回结果。然后rbindlist会将它们合并为一个data.frame。至于警告,在您阅读所有内容之前,您可能不知道问题是什么。只需分两步完成。祝你好运 -
关于框架列表的一个很好的讨论在这里:stackoverflow.com/a/24376207/3358227。虽然该讨论经常偏离将框架保留为列表中的唯一元素,但它确实涉及如何组合它们。
标签: r data.table rbind do.call