如何在R语言中基于参考数据框筛选数据框列表与变量并合并为综合数据框?
问题描述
我有一个包含多个不同变量的数据框列表list_df,想要从中筛选指定数据框和对应变量,最后合并成一个综合数据框。另外还有一个参考数据框VarSel,记录了感兴趣的变量及其所属的数据框。
单独处理单个数据框时,用select(colnames(.) %in% VarSel$Var)就能筛选变量,但不知道怎么用purrr对整个列表批量执行这个操作,求可行的实现方法。
示例数据构造
# 构造数据框列表list_df list_df <- list( df1 = data.frame(ID = 1:5, Age = 20:24, Score = 80:84), df2 = data.frame(ID = 1:5, Gender = c("M", "F", "M", "F", "M"), Score = 80:84, Height = 160:164), df3 = data.frame(ID = 1:5, Weight = 50:54, Age = 20:24) ) # 构造参考数据框VarSel:记录感兴趣的变量及对应数据框 VarSel <- data.frame( DataFrame = c("df1", "df1", "df2", "df3"), Var = c("ID", "Age", "Gender", "Weight") )
期望执行的三步操作
- 从
list_df中筛选出VarSel里提到的数据框 - 对每个筛选出的数据框,只保留
VarSel中对应的数据框的变量 - 将所有处理后的数据框按
ID合并成一个综合数据框
目标输出示例
# 最终目标输出output output <- data.frame( ID = 1:5, Age = 20:24, Gender = c("M", "F", "M", "F", "M"), Weight = 50:54 )
解决方案
结合purrr的映射函数和dplyr的筛选、合并工具即可实现,步骤如下:
步骤1:整理变量映射关系
先把VarSel转换成数据框名称→对应变量列表的命名结构,方便后续批量匹配:
library(dplyr) library(purrr) var_map <- VarSel %>% group_by(DataFrame) %>% summarise(vars = list(Var), .groups = "drop") %>% tibble::deframe() # 转换为命名列表:键是数据框名,值是变量向量
步骤2:批量筛选数据框与变量
先从list_df中提取需要处理的数据框,再用map2批量为每个数据框选择对应变量:
# 筛选出VarSel中提到的数据框 target_dfs <- list_df[names(var_map)] # 对每个数据框,保留指定变量 selected_dfs <- map2(target_dfs, var_map, ~select(.x, all_of(.y)))
这里用all_of()是因为变量以字符向量形式传入,能避免dplyr的引用警告,更规范。
步骤3:合并所有数据框
利用reduce结合left_join,按ID列合并所有处理后的小数据框:
output <- selected_dfs %>% reduce(left_join, by = "ID")
完整整合代码
library(dplyr) library(purrr) # 构造数据 list_df <- list( df1 = data.frame(ID = 1:5, Age = 20:24, Score = 80:84), df2 = data.frame(ID = 1:5, Gender = c("M", "F", "M", "F", "M"), Score = 80:84, Height = 160:164), df3 = data.frame(ID = 1:5, Weight = 50:54, Age = 20:24) ) VarSel <- data.frame( DataFrame = c("df1", "df1", "df2", "df3"), Var = c("ID", "Age", "Gender", "Weight") ) # 执行流程 output <- VarSel %>% group_by(DataFrame) %>% summarise(vars = list(Var), .groups = "drop") %>% tibble::deframe() %>% {list_df[names(.)]} %>% map2(., names(.) %>% map(~filter(VarSel, DataFrame == .x)$Var), ~select(.x, all_of(.y))) %>% reduce(left_join, by = "ID") # 查看结果 output
运行后得到的output即为期望的综合数据框。
内容的提问来源于stack exchange,提问作者pgourdon
相关产品推荐
相关产品推荐

