You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 04:32:05