在R语言中将行中值为1的列名提取至单列
问题描述
现有如下DataFrame:
Patient Gene1 Gene2 Gene3 Gene4 patienta 1 0 0 1 patientb 0 1 0 0 patientc 0 1 1 1
需要提取每行中值为1对应的列名,期望输出如下:
Patient Gene patienta Gene1 patienta Gene4 patientb Gene2 patientc Gene2 patientc Gene3 patientc Gene4
能否使用list或lapply函数实现?
解决方案
当然可以用lapply实现,以下是两种可行的实现方式:
方法一:lapply逐行生成子数据框后合并
先构造示例数据(如果已有数据可跳过这一步),然后通过lapply遍历每一行,筛选出值为1的基因列名,再和对应患者名组合成子数据框,最后合并所有子数据框得到结果:
# 构造示例数据框 df <- data.frame( Patient = c("patienta", "patientb", "patientc"), Gene1 = c(1, 0, 0), Gene2 = c(0, 1, 1), Gene3 = c(0, 0, 1), Gene4 = c(1, 0, 1), stringsAsFactors = FALSE ) # 提取所有基因列的列名 gene_names <- colnames(df)[-1] # 用lapply处理每一行 row_results <- lapply(1:nrow(df), function(row_idx) { # 筛选当前行值为1的基因列名 target_genes <- gene_names[df[row_idx, -1] == 1] # 组合患者名与基因名,生成子数据框 data.frame(Patient = df$Patient[row_idx], Gene = target_genes, stringsAsFactors = FALSE) }) # 合并所有子数据框 final_output <- do.call(rbind, row_results) print(final_output)
方法二:通过列表展开实现
先通过apply按行提取每个患者对应的基因列表,再分别生成重复的患者名列表和展开的基因列表,最后组合成结果数据框:
# 基于上面的df数据,提取每行值为1的基因列名,生成列表 gene_list <- apply(df[, -1], 1, function(row_data) gene_names[row_data == 1]) # 根据每个患者的基因数量,重复对应的患者名 patient_vec <- rep(df$Patient, sapply(gene_list, length)) # 展开基因列表为向量 gene_vec <- unlist(gene_list) # 组合成结果数据框 final_output <- data.frame(Patient = patient_vec, Gene = gene_vec, stringsAsFactors = FALSE) print(final_output)
两种方法都用到了列表相关操作,最终都能输出你需要的格式。
内容的提问来源于stack exchange,提问作者Aryh
相关产品推荐
相关产品推荐

