如何在R语言中创建列标记存在非NA值的对应分组?
问题描述
我有5列不同的p值数据,希望生成一个新列,标记出每一行中哪些分组对应的p值列存在非NA值。
输入数据结构:
Gene pvalue_group1 pvalue_group2 pvalue_group3 pvalue_group4 pvalue_group5 Gene1 0.01 0.2 NA NA NA Gene2 NA 0.001 NA NA NA Gene3 0.05 0.7 0.09 0.2 0.001
期望输出(新增Group列):
Gene pvalue_group1 pvalue_group2 pvalue_group3 pvalue_group4 pvalue_group5 Group Gene1 0.01 0.2 NA NA NA Group1, Group2 Gene2 NA 0.001 NA NA NA Group2 Gene3 0.05 0.7 0.09 0.2 0.001 Group1, Group2, Group3, Group4, Group5
示例输入数据:
df <- structure(list(Gene = c("Gene1", "Gene2", "Gene3"), pvalue_group1 = c(0.01, NA, 0.05), pvalue_group2 = c(0.2, 0.001, 0.7), pvalue_group3 = c(NA, NA, 0.09), pvalue_group4 = c(NA, NA, 0.2), pvalue_group5 = c(NA, NA, 0.001)), row.names = c(NA, -3L), class = c("data.table", "data.frame"))
我尝试用dplyr的mutate()函数实现但未成功,希望了解其他可行的函数和方法。
解决方案
方法1:修正dplyr实现
结合rowwise()、across()和字符串处理函数即可完成,之前的尝试可能缺少行级处理的步骤:
library(dplyr) library(stringr) df <- df %>% rowwise() %>% mutate( Group = str_c( str_remove(names(select(., starts_with("pvalue_group")))[!is.na(c_across(starts_with("pvalue_group")))], "pvalue_"), collapse = ", " ) ) %>% ungroup()
方法2:data.table原生语法(适配输入类型)
因为输入是data.table格式,用原生语法效率更高:
library(data.table) # 筛选p值列并提取分组名 p_cols <- grep("^pvalue_group", names(df), value = TRUE) group_names <- sub("pvalue_", "", p_cols) # 逐行生成Group列 df[, Group := { p_vals <- .SD paste(group_names[!is.na(p_vals)], collapse = ", ") }, .SDcols = p_cols]
方法3:基础R实现(无需第三方包)
如果不想加载额外包,用apply()逐行处理即可:
# 获取p值列的索引和分组名 p_cols_idx <- grep("^pvalue_group", names(df)) group_names <- sub("pvalue_", "", names(df)[p_cols_idx]) # 生成Group列 df$Group <- apply(df[, p_cols_idx], 1, function(x) { paste(group_names[!is.na(x)], collapse = ", ") })
内容的提问来源于stack exchange,提问作者DN1
相关产品推荐
相关产品推荐

