统计两个嵌套列表对应元素的公共子元素数量
问题与解决方案
需求说明
现有两个嵌套列表list1和list2,二者的顶级元素名称均为ENSG编号。需要针对每个ENSG编号,统计两个列表中对应子元素(格式为chrXX_XXXX_X_X_b38的列名)的公共数量,最终输出包含两列的数据框:第一列为ENSG编号,第二列为公共子元素的数量。
输入列表
list1
list1 <- list(ENSG00000040608 = structure(list(chr22_20230714_G_A_b38 = 0.0000953181301665087, chr22_20230737_G_A_b38 = -0.00124036704551427, chr22_20231229_T_A_b38 = 0.000808061558738542, chr22_20231474_G_A_b38 = 0.000387528601423933, chr22_20231667_C_G_b38 = -0.000120624028990859), row.names = c(NA, -1L), class = c("tbl_df", "tbl", "data.frame")), ENSG00000020766 = structure(list(chr22_47157062_G_A_b38 = 0.00000909931572319958, chr22_47157212_G_A_b38 = -0.000124084106569373, chr22_47157394_C_G_b38 = -0.0000752774417069946, chr22_47157559_G_A_b38 = 0.0000808446315377557, chr22_47157607_T_C_b38 = 0.000237979025556899), row.names = c(NA, -1L), class = c("tbl_df", "tbl", "data.frame")))
list2
list2 <- list(ENSG00000040608 = structure(list(chr22_20230714_G_A_b38 = c(1L, 1L, 1L, 2L, 1L), chr22_20230737_G_A_b38 = c(0L, 0L, 0L, 0L, 0L), chr22_20231229_T_A_b38 = c(1L, 0L, 1L, 0L, 1L), chr22_20231555_A_T_b38 = c(0L,1L, 0L, 0L, 0L), chr22_20231667_C_G_b38 = c(1L, 1L, 1L, 2L, 1L)), row.names = c(NA, -5L), class = c("tbl_df", "tbl", "data.frame")), ENSG00000020766 = structure(list(chr22_47157062_G_A_b38 = c(0L,1L, 0L, 0L, 0L), chr22_47157212_G_A_b38 = c(0L, 0L, 1L, 1L, 2L), chr22_47157394_C_G_b38 = c(0L, 1L, 1L, 1L, 2L), chr22_47207559_T_C_b38 = c(0L, 1L, 0L, 0L, 0L)), row.names = c(NA, -4L), class = c("tbl_df", "tbl", "data.frame")))
解决方案
方法1:基础R实现
# 提取每个ENSG对应的子元素列名 list1_cols <- lapply(list1, colnames) list2_cols <- lapply(list2, colnames) # 计算每个ENSG的公共子元素数量 common_counts <- mapply(function(x, y) length(intersect(x, y)), list1_cols, list2_cols) # 转换为目标数据框 result_df <- data.frame( ENSGs = names(common_counts), Common_Count = as.numeric(common_counts), row.names = NULL ) # 输出结果 print(result_df)
方法2:tidyverse实现
library(tidyverse) result_df <- tibble(ENSGs = names(list1)) %>% mutate( # 获取list1中每个ENSG的子元素列名 list1_subs = map(list1, colnames), # 获取list2中对应ENSG的子元素列名 list2_subs = map(ENSGs, ~colnames(list2[[.x]])), # 统计公共子元素数量 Common_Count = map2_int(list1_subs, list2_subs, ~length(intersect(.x, .y))) ) %>% select(ENSGs, Common_Count) # 输出结果 print(result_df)
运行结果
两种方法都会得到如下数据框:
ENSGs Common_Count 1 ENSG00000040608 4 2 ENSG00000020766 3
逻辑说明
- 每个ENSG对应的子元素是嵌套列表中数据框的列名,因此先提取每个数据框的列名;
- 对每一组ENSG的列名集合取交集,用
length()统计交集元素的数量; - 将结果整理成包含ENSG编号和公共数量的两列数据框。
内容的提问来源于stack exchange,提问作者Maya_Cent
相关产品推荐
相关产品推荐

