如何在R语言中重塑基因型数据框为指定格式?
R语言数据框重塑方案
原始数据
df <- data.frame(SNP = c("rs123","rs567"), A1 = c("A","C"), A2 = c("G","T"), A1A1.x = c(16,52), A1A2.x = c(104,342), A2A2.x = c(127,408), A1A1.y = c(14,80), A1A2.y = c(122,186), A2A2.y = c(107,183), P_HWE = c(0.4293,0.09432), A1A1_x = c(6.4777328,6.4837905), A1A2_x = c(42.10526,42.64339), A2A2_x = c(51.417,50.87282), A1A1_y = c(5.7613169,17.8173719), A1A2_y = c(50.20576,41.42539), A2A2_y = c(44.03292,40.75724))
目标格式
SNP A1 A2 Genotypes n_controls f_controls n_cases f_cases P_HWE rs123 A G AA 16 6.4777328 14 5.7613169 0.4293 rs123 A G GA 104 42.10526 122 50.20576 0.4293 rs123 A G GG 127 51.417 107 44.03292 0.4293 rs567 C T CC 52 6.4837905 80 17.8173719 0.09432 rs567 C T TC 342 42.64339 186 41.42539 0.09432 rs567 C T TT 408 50.87282 183 40.75724 0.09432
实现方法
方法一:tidyverse工具链(推荐)
先安装并加载tidyverse包:
install.packages("tidyverse") library(tidyverse)
拆分处理计数(n)和频率(f)数据,再合并生成目标格式:
# 处理控制组/病例组的计数数据(.x/.y后缀) n_data <- df %>% select(SNP, A1, A2, P_HWE, matches("\\.x|\\.y")) %>% pivot_longer(cols = matches("\\.x|\\.y"), names_to = c("geno_code", "group"), names_sep = "\\.", values_to = "n") %>% pivot_wider(names_from = group, values_from = n) %>% rename(n_controls = x, n_cases = y) # 处理控制组/病例组的频率数据(_x/_y后缀) f_data <- df %>% select(SNP, A1, A2, P_HWE, matches("_x|_y")) %>% pivot_longer(cols = matches("_x|_y"), names_to = c("geno_code", "group"), names_sep = "_", values_to = "f") %>% pivot_wider(names_from = group, values_from = f) %>% rename(f_controls = x, f_cases = y) # 合并数据并生成基因型显示列 result <- n_data %>% inner_join(f_data, by = c("SNP", "A1", "A2", "P_HWE", "geno_code")) %>% mutate(Genotypes = case_when( geno_code == "A1A1" ~ str_c(A1, A1), geno_code == "A1A2" ~ str_c(A2, A1), # 对应目标格式的GA/TC geno_code == "A2A2" ~ str_c(A2, A2) )) %>% # 调整列顺序匹配目标格式 select(SNP, A1, A2, Genotypes, n_controls, f_controls, n_cases, f_cases, P_HWE) # 查看结果 print(result, row.names = FALSE)
方法二:Base R(无需额外包)
如果不想加载外部包,可以用Base R的reshape函数处理:
# 拆分计数和频率数据框 n_df <- df[, c("SNP", "A1", "A2", "A1A1.x", "A1A2.x", "A2A2.x", "A1A1.y", "A1A2.y", "A2A2.y", "P_HWE")] f_df <- df[, c("SNP", "A1", "A2", "A1A1_x", "A1A2_x", "A2A2_x", "A1A1_y", "A1A2_y", "A2A2_y", "P_HWE")] # 将计数数据转长格式 n_long <- reshape(n_df, varying = list(c("A1A1.x", "A1A2.x", "A2A2.x"), c("A1A1.y", "A1A2.y", "A2A2.y")), v.names = c("n_controls", "n_cases"), times = c("AA", "GA", "GG"), timevar = "Genotypes", direction = "long") # 将频率数据转长格式 f_long <- reshape(f_df, varying = list(c("A1A1_x", "A1A2_x", "A2A2_x"), c("A1A1_y", "A1A2_y", "A2A2_y")), v.names = c("f_controls", "f_cases"), times = c("AA", "GA", "GG"), timevar = "Genotypes", direction = "long") # 合并数据并整理 result_base <- merge(n_long[, -c("id")], f_long[, -c("id")], by = c("SNP", "A1", "A2", "Genotypes", "P_HWE")) # 调整列顺序并按SNP排序 result_base <- result_base[order(result_base$SNP), ] result_base <- result_base[, c("SNP", "A1", "A2", "Genotypes", "n_controls", "f_controls", "n_cases", "f_cases", "P_HWE")] # 查看结果 print(result_base, row.names = FALSE)
内容的提问来源于stack exchange,提问作者Yannick
相关产品推荐
相关产品推荐

