如何在R中从数据框列表批量提取列生成合并数据框
批量合并数据框列表生成宽格式数据框
需求描述
我有一个包含多个数据框的列表split_plot_data2,每个子数据框结构一致,包含EE_variant、lambda、variable和value列。需要生成一个合并后的宽格式数据框:
- 以所有子数据框通用的
variable列为第一列(重命名为Variable) - 每个子数据框的
lambda列单独成一列,列名格式为Lambda_<对应EE_variant值> - 子数据框行数不一致时,行数不足的位置自动补
NA
当前手动逐个添加列的方式效率低下,寻求批量实现方案。
数据示例
head(split_plot_data2) $EE87786ln1 # A tibble: 1,584 × 4 EE_variant lambda variable value <chr> <dbl> <chr> <dbl> 1 EE87786ln1 0.0000228 blood_vessel_h16 0 2 EE87786ln1 0.0000228 adrenal_gland_h16 0 3 EE87786ln1 0.0000228 bone_element_h16 0 4 EE87786ln1 0.0000228 Bronchus_h16 0 5 EE87786ln1 0.0000228 esophagus_h16 0 6 EE87786ln1 0.0000228 extraembryonic_structure_h16 0 7 EE87786ln1 0.0000228 eye_h16 0 8 EE87786ln1 0.0000228 gonad_h16 0 9 EE87786ln1 0.0000228 heart_h16 0 10 EE87786ln1 0.0000228 kidney_h16 0 # ℹ 1,574 more rows # ℹ Use `print(n = ...)` to see more rows $EE87787ln1 # A tibble: 1,560 × 4 EE_variant lambda variable value <chr> <dbl> <chr> <dbl> 1 EE87787ln1 0.0000751 blood_vessel_h16 0 2 EE87787ln1 0.0000751 adrenal_gland_h16 0 3 EE87787ln1 0.0000751 bone_element_h16 0 4 EE87787ln1 0.0000751 Bronchus_h16 0 5 EE87787ln1 0.0000751 esophagus_h16 0 6 EE87787ln1 0.0000751 extraembryonic_structure_h16 0 7 EE87787ln1 0.0000751 eye_h16 0 8 EE87787ln1 0.0000751 gonad_h16 0 9 EE87787ln1 0.0000751 heart_h16 0 10 EE87787ln1 0.0000751 kidney_h16 0 # ℹ 1,550 more rows # ℹ Use `print(n = ...)` to see more rows
预期结果
head(comb_plot_lamb) # A tibble: 6 × 8 Variable Lambda_EE87802 Lambda_EE87786 Lambda_EE87787 Lambda_EE87788 Lambda_EE87789 Lambda_EE87790 Lambda_EE87791 <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> 1 blood_vessel_h16 0.0000348 0.0000228 0.0000751 0.0000761 0.0000732 0.0000328 0.0000444 2 adrenal_gland_h16 0.0000348 0.0000228 0.0000751 0.0000761 0.0000732 0.0000328 0.0000444 3 bone_element_h16 0.0000348 0.0000228 0.0000751 0.0000761 0.0000732 0.0000328 0.0000444 4 Bronchus_h16 0.0000348 0.0000228 0.0000751 0.0000761 0.0000732 0.0000328 0.0000444 5 esophagus_h16 0.0000348 0.0000228 0.0000751 0.0000761 0.0000732 0.0000328 0.0000444 6 extraembryonic_struct… 0.0000348 0.0000228 0.0000751 0.0000761 0.0000732 0.0000328 0.0000444
现有低效代码(手动添加列)
n1 <- sapply(split_plot_data2, nrow) n2 <- max(n1) n4 <- which.max(n1) comb_plot_data <- split_plot_data2[[n4]][1:4] comb_plot_data2 <- comb_plot_data[, c(3,2)] colnames(comb_plot_data2) <- c('Variable','Lambda_EE87802') comb_plot_lamb <- comb_plot_data2 comb_plot_lamb$Lambda_EE87786 <- c(split_plot_data2[[1]]$lambda, rep(NA, nrow(comb_plot_lamb)-length(split_plot_data2[[1]]$lambda))) comb_plot_lamb$Lambda_EE87787 <- c(split_plot_data2[[2]]$lambda, rep(NA, nrow(comb_plot_lamb)-length(split_plot_data2[[2]]$lambda))) comb_plot_lamb$Lambda_EE87788 <- c(split_plot_data2[[3]]$lambda, rep(NA, nrow(comb_plot_lamb)-length(split_plot_data2[[3]]$lambda))) comb_plot_lamb$Lambda_EE87789 <- c(split_plot_data2[[4]]$lambda, rep(NA, nrow(comb_plot_lamb)-length(split_plot_data2[[4]]$lambda))) comb_plot_lamb$Lambda_EE87790 <- c(split_plot_data2[[5]]$lambda, rep(NA, nrow(comb_plot_lamb)-length(split_plot_data2[[5]]$lambda))) comb_plot_lamb$Lambda_EE87791 <- c(split_plot_data2[[6]]$lambda, rep(NA, nrow(comb_plot_lamb)-length(split_plot_data2[[6]]$lambda)))
批量实现方案
方案1:使用tidyverse工具链(推荐)
利用purrr遍历列表,dplyr筛选列,tidyr转换为宽格式,自动处理行匹配和NA填充:
library(tidyverse) # 遍历每个子数据框,只保留需要的列 processed_list <- map(split_plot_data2, ~select(.x, variable, lambda, EE_variant)) # 合并所有数据框并转宽格式 comb_plot_lamb <- bind_rows(processed_list) %>% pivot_wider( names_from = EE_variant, # 用EE_variant的值作为新列名 values_from = lambda, # 用lambda的值填充新列 names_prefix = "Lambda_" # 给新列名添加前缀 ) %>% rename(Variable = variable) # 将variable列重命名为Variable
方案2:基础R实现(无额外依赖)
如果不想加载tidyverse包,用基础R循环+匹配的方式实现:
# 获取所有子数据框的名称(即EE_variant值) ee_variants <- names(split_plot_data2) # 找到行数最多的子数据框,用它的variable列作为基础 max_row_idx <- which.max(sapply(split_plot_data2, nrow)) comb_plot_lamb <- data.frame(Variable = split_plot_data2[[max_row_idx]]$variable) # 循环遍历每个子数据框,添加对应的lambda列 for (var in ee_variants) { current_df <- split_plot_data2[[var]] # 根据variable匹配,自动补NA到对应行 comb_plot_lamb[[paste0("Lambda_", var)]] <- current_df$lambda[match(comb_plot_lamb$Variable, current_df$variable)] }
这两个方案都能自动处理子数据框行数不一致的情况,无需手动计算补NA的数量,且支持任意数量的子数据框,无需逐个修改代码。
内容的提问来源于stack exchange,提问作者Debajyoti Kabiraj
相关产品推荐
相关产品推荐

