如何在R中依据df1内容高效填充df2并标记匹配的突变信息
R中实现长表转存在性宽表的高效方案
核心逻辑
本质是将ID-突变一对一的长格式表,转换为行=ID、列=突变类型、存在即标记Y的宽格式表,针对数百ID、20余种突变的业务规模,以下三类方案均能满足性能需求,可按使用习惯选择:
方案1:tidyverse 方案(易读易维护,最常用)
依赖tidyr、dplyr包,代码可读性高,中小规模数据性能完全适配:
# 加载依赖(首次使用需先安装:install.packages("tidyverse")) library(tidyverse) # 1. 构造示例长表df1 df1 <- tibble( ID = c(1, 2, 2, 3), Mutation = c("A", "B", "C", "A") ) # 2. 预处理:去重(避免同ID-突变重复记录导致宽表异常,无重复可省略) df1_clean <- df1 %>% distinct(ID, Mutation) # 3. 生成目标宽表df2 df2 <- df1_clean %>% # 新增存在标记列 mutate(flag = "Y") %>% # 宽展:突变作为列名,标记作为值,缺失位置填充NA(打印时显示空白,匹配示例效果) pivot_wider( names_from = Mutation, values_from = flag, values_fill = NA ) # 查看输出 df2
输出结果完全匹配需求:
# A tibble: 3 × 3 ID A B C <dbl> <chr> <chr> <chr> 1 1 Y NA NA 2 2 NA Y Y 3 3 Y NA NA
方案2:基础R 方案(无第三方包依赖)
适合无法安装额外包的极简场景:
# 1. 生成ID-突变存在性列联表 cont_table <- table(df1$ID, df1$Mutation) # 2. 转换为数据框,替换数值标记 df2_base <- as.data.frame.matrix(cont_table) df2_base[df2_base == 1] <- "Y" df2_base[df2_base == 0] <- NA # 3. 将行名(ID)转为独立列 df2_base <- cbind(ID = as.integer(rownames(df2_base)), df2_base) rownames(df2_base) <- NULL # 清除冗余行名 df2_base
方案3:data.table 方案(超高效,适配更大规模扩展)
如果后续业务数据量升级到数千ID、上百种突变,该方案的内存效率、运行速度优势显著:
# 加载依赖(首次使用需先安装:install.packages("data.table")) library(data.table) # 1. 转换为data.table格式,去重同ID-突变对 dt1 <- as.data.table(df1) dt1_clean <- dt1[, .SD[1], by = .(ID, Mutation)] # 2. 宽展生成目标表 dt2 <- dcast( dt1_clean, ID ~ Mutation, fun.aggregate = length, fill = NA ) # 3. 将计数结果替换为"Y"标记(突变列动态获取,无需硬编码) mut_cols <- setdiff(names(dt2), "ID") for (col in mut_cols) { dt2[get(col) == 1, (col) := "Y"] } dt2
注意事项
- 去重步骤不可省略:如果df1存在同ID-同一突变的重复录入,宽展会生成嵌套值,必须先去重。
- 缺失值可按需调整:如果需要用空字符串而非NA填充无突变的位置,修改
values_fill/fill参数为""即可。 - 列顺序自定义:如果需要固定突变列的顺序(而非默认字母排序),可在宽展前用
forcats::fct_relevel(Mutation, "A", "B", "C")固定因子层级。
内容的提问来源于stack exchange,提问作者Lei Deng
相关产品推荐
相关产品推荐

