R语言如何将原始data.frame的缺失列回填到data.frame列表
问题描述
我从data生成了data.frame列表LIST,但LIST缺失了原始data中存在的paper列(注:缺失列的列名会明确给出)。
我想将缺失的paper列回填到LIST的每个元素中,得到DESIRED_LIST的效果,之前尝试的方案如下:lapply(LIST, function(x)data[do.call(paste, data[names(x)]) %in% do.call(paste, x),])
但运行后无法得到目标输出,希望得到Base R或tidyverse风格的实现方案。
原有方案失效的原因是直接筛选原始全量data的行,会把原始数据中ES、bar等不需要的列一并返回,且没有处理同匹配键对应多行的重复问题。
可复现示例数据
m2=" paper study sample comp ES bar 1 1 1 1 1 7 1 2 2 2 2 6 1 2 3 3 3 5 2 3 4 4 4 4 2 3 4 4 5 3 2 3 4 5 6 2 2 3 4 5 7 1" data <- read.table(text=m2,h=T) LIST <- list(data.frame(study=1 ,sample=1 ,comp=1), data.frame(study=rep(3,4),sample=rep(4,4),comp=c(4,4,5,5)), data.frame(study=c(2,2) ,sample=c(2,3) ,comp=c(2,3))) DESIRED_LIST <- list(data.frame(paper=1 ,study=1 ,sample=1 ,comp=1), data.frame(paper=rep(2,4),study=rep(3,4),sample=rep(4,4),comp=c(4,4,5,5)), data.frame(paper=rep(1,2),study=c(2,2) ,sample=c(2,3) ,comp=c(2,3)))
解决方案
Base R 实现
核心逻辑是先提取匹配键和paper的唯一映射,再遍历列表做合并,避免返回多余列和重复行:
# 提取匹配键与paper的唯一映射关系 key_map <- unique(data[, c("study", "sample", "comp", "paper")]) # 遍历列表元素做匹配合并 result <- lapply(LIST, function(df) { merge(df, key_map, by = c("study", "sample", "comp"), sort = FALSE) })
验证:identical(result, DESIRED_LIST) 返回 TRUE。
Tidyverse 实现
用purrr遍历列表,dplyr做关联匹配:
library(tidyverse) result <- LIST %>% map( ~ left_join(.x, distinct(data, study, sample, comp, paper), by = c("study", "sample", "comp")) )
内容的提问来源于stack exchange,提问作者Reza
相关产品推荐
相关产品推荐

