如何在内存不足时拆分列表中的DataFrame并按年份合并
按年份分组合并大型列表数据集(避免内存溢出)
当你有一个包含多个数据框的列表,每个数据框包含不同年份的观测值,想要将同一年份的记录合并到同一数据集时,常规的先全量合并再拆分的方法会因数据集过大导致内存不足。这里提供两种无需先全量合并的解决方案:
示例数据
mydata1<-data.frame(ID=1:5, year=c(2011:2015),Weight=c(50:54)) mydata2<-data.frame(ID=6:10, year=c(2011:2013,2011,2014),Weight=c(52:56)) mydata3<-data.frame(ID=11:15, year=c(2011:2013,2011,2015),Weight=c(61:65)) mydata4<-data.frame(ID=16:20, year=c(2012:2014,2015,2013),Weight=c(70:74)) mydatalist<-list(mydata1=mydata1, mydata2=mydata2, mydata3=mydata3, mydata4=mydata4)
方案一:Base R实现
先逐个拆分列表中的每个数据框,再按年份合并对应部分:
# 1. 对列表内每个数据框按年份拆分 split_per_df <- lapply(mydatalist, function(df) split(df, df$year)) # 2. 获取所有唯一年份 all_years <- unique(unlist(lapply(split_per_df, names))) # 3. 按年份合并各数据框中对应年份的记录 year_grouped_data <- lapply(all_years, function(year) { do.call(rbind, lapply(split_per_df, function(splitted) splitted[[as.character(year)]])) }) # 给结果列表命名为对应年份 names(year_grouped_data) <- all_years
方案二:使用purrr包简化代码
利用purrr的函数式编程能力,更简洁地实现需求:
library(purrr) library(dplyr) year_grouped_data <- mydatalist %>% # 逐个拆分每个数据框为按年份分组的子列表 map(~split(.x, .x$year)) %>% # 转置嵌套列表,将同一年份的子数据框归为一组 transpose() %>% # 合并每组内的所有数据框 map(bind_rows)
两种方案都避免了一次性加载全量合并的数据,大幅降低内存占用,最终得到的year_grouped_data是一个列表,每个元素对应一个年份的合并数据集。
内容的提问来源于stack exchange,提问作者Seydou GORO
相关产品推荐
相关产品推荐

