在R语言中实现两个列表对应列元素相乘的方法
解决方案:列表对应列元素批量相乘
问题背景
给定两个R列表list1和list2:
list1的每个元素是仅含1行的tibble,列名为SNP标识,值为系数list2的每个元素是多行tibble,包含样本信息列(name、ENSG、expr)和对应SNP列,值为样本的基因型计数- 两个列表的元素数量一致,对应元素的SNP列名完全匹配
需求:将list1中每个元素的各SNP系数,与list2对应元素的同列SNP值逐一相乘,保留list2的样本信息列,替换SNP列为相乘后的结果,同时保留数据结构。
输入数据
list1
list1 <- list(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")), 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(structure(list(name = c("HG00096", "HG00097", "HG00099", "HG00100", "HG00101"), ENSG = c("ENSG00000040608", "ENSG00000040608", "ENSG00000040608", "ENSG00000040608", "ENSG00000040608"), expr = c(-0.5186894, 0.6170779, -0.5786774, 0.07324268, -0.7579184), 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_20231474_G_A_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" )), structure(list(name = c("HG00096", "HG00097", "HG00099", "HG00100", "HG00101"), ENSG = c("ENSG00000054611", "ENSG00000054611", "ENSG00000054611", "ENSG00000054611", "ENSG00000054611"), expr = c(-0.5555929, 0.1600335, 0.4027508, -0.6028474, 2.271097), 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_47157559_G_A_b38 = c(0L, 1L, 0L, 0L, 0L), chr22_47157607_T_C_b38 = c(0L, 1L, 1L, 1L, 2L )), row.names = c(NA, -5L), class = c("tbl_df", "tbl", "data.frame" )))
解决方案代码
使用purrr包的map2函数批量处理两个列表的对应元素,结合dplyr进行列运算:
library(purrr) library(dplyr) out <- map2(list2, list1, function(df2, df1) { # 获取SNP列名 snp_cols <- names(df1) # 对每个SNP列执行相乘运算,同时保留样本信息列 df2 %>% mutate(across(all_of(snp_cols), ~ .x * df1[[cur_column()]])) %>% # 匹配示例精度保留小数位数(可选) mutate(across(all_of(snp_cols), ~ round(.x, 6))) })
验证结果
运行代码后,out的结构和值与预期输出一致:
print(out)
输出结果:
out <- list(structure(list(name = c("HG00096", "HG00097", "HG00099", "HG00100", "HG00101"), ENSG = c("ENSG00000040608", "ENSG00000040608", "ENSG00000040608", "ENSG00000040608", "ENSG00000040608"), expr = c(-0.5186894, 0.6170779, -0.5786774, 0.07324268, -0.7579184), chr22_20230714_G_A_b38 = c(0.000095, 0.000095, 0.000095, 0.000191, 0.000095), chr22_20230737_G_A_b38 = c(0, 0, 0, 0, 0), chr22_20231229_T_A_b38 = c(0.000808, 0, 0.000808, 0, 0.000808), chr22_20231474_G_A_b38 = c(0, 0.000388, 0, 0, 0 ), chr22_20231667_C_G_b38 = c(-0.000121, -0.000121, -0.000121, -0.000241, -0.000121)), row.names = c(NA, -5L), class = c("tbl_df", "tbl", "data.frame")), structure(list(name = c("HG00096", "HG00097", "HG00099", "HG00100", "HG00101"), ENSG = c("ENSG00000054611", "ENSG00000054611", "ENSG00000054611", "ENSG00000054611", "ENSG00000054611" ), expr = c(-0.5555929, 0.1600335, 0.4027508, -0.6028474, 2.271097 ), chr22_47157062_G_A_b38 = c(0, 0.000009, 0, 0, 0), chr22_47157212_G_A_b38 = c(0, 0, -0.000124, -0.000124, -0.000248), chr22_47157394_C_G_b38 = c(0, -0.000075, -0.000075, -0.000075, -0.000151), chr22_47157559_G_A_b38 = c(0, 0.000081, 0, 0, 0), chr22_47157607_T_C_b38 = c(0, 0.000238, 0.000238, 0.000238, 0.000476)), row.names = c(NA, -5L), class = c("tbl_df", "tbl", "data.frame")))
内容的提问来源于stack exchange,提问作者Maya_Cent
相关产品推荐
相关产品推荐

