R语言:将行数不同的data.frame列表合并为带NA补全的data.frame
合并行数不同的带行名单列data.frame列表(缺失值填充NA)
首先构造示例数据方便复现:
# 构造示例数据 mylist <- list( elem1 = data.frame(elem1 = c("E7", "E7", "E4", "E8", "E9", "E8"), row.names = paste0("sample-", sprintf("%02d", 1:6))), elem2 = data.frame(elem2 = c("E1", "E1", "E8", "E3"), row.names = paste0("sample-", sprintf("%02d", 1:4))), elem3 = data.frame(elem3 = c("E2", "E2", "E7", "E2"), row.names = paste0("sample-", sprintf("%02d", 5:8))) )
方法一:Base R 实现
通过收集所有行名,逐个合并并保留所有行:
# 获取所有唯一行名 all_samples <- unique(unlist(lapply(mylist, rownames))) # 初始化结果data.frame result_base <- data.frame(row.names = all_samples) # 循环合并每个列表元素 for (df in mylist) { result_base <- merge(result_base, df, by = "row.names", all.x = TRUE) rownames(result_base) <- result_base$Row.names result_base$Row.names <- NULL } # 按行名排序(确保顺序为sample-01到sample-08) result_base <- result_base[order(rownames(result_base)), ]
方法二:tidyverse 实现(更简洁)
利用dplyr和purrr的函数链,先转长格式再转宽格式:
library(tidyverse) result_tidy <- mylist %>% # 为每个data.frame添加行名列,保留原列表元素名作为列标识 imap(~ .x %>% rownames_to_column("sample")) %>% # 绑定所有行 bind_rows() %>% # 转宽格式,缺失值填充NA pivot_wider( names_from = .y, values_from = starts_with("elem"), values_fill = NA ) %>% # 将sample列转回行名 column_to_rownames("sample") %>% # 按行名排序 arrange(rownames(.))
两种方法最终都会得到目标格式:
elem1 elem2 elem3 sample-01 E7 E1 NA sample-02 E7 E1 NA sample-03 E4 E8 NA sample-04 E8 E3 NA sample-05 E9 NA E2 sample-06 E8 NA E2 sample-07 NA NA E7 sample-08 NA NA E2
内容的提问来源于stack exchange,提问作者abraham
相关产品推荐
相关产品推荐

