# 使用 Ensembl API 查询 SNP 在不同人群中的分布

Ensembl REST API 的端点和测试用例可以在这里找到。本文以 R 语言为例,介绍如何使用 Ensembl API 查询特定单核苷酸多态性(SNP)的分布情况,包括单个和批量查询的实现过程。

# 为什么要查询 SNP 的分布?

SNP(单核苷酸多态性)是基因组中常见的变异形式,对研究基因与表型的关系、疾病关联分析和个性化医疗至关重要。SNP 在不同人群中的分布往往因种群历史、地理分布和自然选择而异,因此理解这些分布特征是遗传学研究的重要任务。

# 准备工作

需要加载几个 R 包来完成请求和数据处理:

library(httr)       # 用于发送 HTTP 请求
library(jsonlite)   # 用于解析和构造 JSON 数据
library(dplyr)      # 用于数据操作

# 单个 SNP 的查询

# API 调用和数据处理

以下代码实现了查询单个 SNP ( rs3762444 ) 的频率分布:

server <- "https://grch37.rest.ensembl.org"
ext <- "/variation/human/rs3762444?pops=1"
r <- GET(paste(server, ext, sep = ""), content_type("application/json"))
stop_for_status(r)
response <- content(r, as = "parsed", type = "application/json")
pg <- response[["populations"]] %>% bind_rows(lapply(., as.data.frame))
print(pg)

# 代码解析

  1. API URL 构建:
    • server 是 Ensembl API 的基础 URL。
    • ext 是指定资源的扩展路径,包括要查询的 SNP ID( rs3762444 )和额外参数( pops=1 表示返回人群频率信息)。
  2. 发送 GET 请求:
    • 使用 GET 方法向服务器发送请求,并确保请求成功( stop_for_status )。
  3. 数据解析:
    • response 包含服务器返回的 JSON 数据。
    • 提取 populations 字段(包含频率数据)并将其转换为数据框格式。

# 输出结果

查询结果 pg 是一个数据框,展示了 rs3762444 在不同人群中的频率分布。例如:

Population Name Allele Frequency
1000GENOMES:AFR T 0.123
1000GENOMES:EUR C 0.789

# 批量查询多个 SNP

当需要查询多个 SNP 时,可以使用 POST 请求。以下代码实现了批量查询:

server <- "https://grch37.rest.ensembl.org"
ext <- "/variation/homo_sapiens?pops=1"
body <- list(
  ids = list("rs3762444", "rs284262", "rs655598")
)
json_body <- toJSON(body, auto_unbox = TRUE, pretty = TRUE)
r <- POST(paste(server, ext, sep = ""), 
          content_type("application/json"), 
          accept("application/json"), 
          body = json_body)
stop_for_status(r)
response <- content(r, as = "parsed", type = "application/json")
pg <- lapply(response, function(data) {
  bind_rows(lapply(data[["populations"]], as.data.frame))
})
print(pg)

# 代码解析

  1. 构建请求体:
    • 使用一个列表 body 指定要查询的多个 SNP ID。
    • 将列表转换为 JSON 格式( toJSON )。
  2. 发送 POST 请求:
    • 使用 POST 方法发送请求,并指定 body
    • 设置 HTTP headers,包括 content_typeaccept
  3. 解析结果:
    • response 是一个列表,包含每个 SNP 的查询结果。
    • 遍历结果,提取 populations 字段并转换为数据框。

# 输出结果

批量查询结果 pg 是一个列表,其中每个元素对应一个 SNP 的频率数据。例如:

  • pg[[1]]rs3762444 的频率分布。
  • pg[[2]]rs284262 的频率分布。

每个数据框的结构类似于单个查询的结果。

# 完整代码

library(httr)
library(jsonlite)
library(dplyr)
################################### 单个 ###################################
rm(list = ls())
setwd("D:/Study/Project/GDG/labtd/workfile/other/黄煜/20241206")
server <- "https://grch37.rest.ensembl.org"
ext <- "/variation/human/rs3762444?pops=1"
r <- GET(paste(server, ext, sep = ""), content_type("application/json"))
stop_for_status(r)
response <- content(r, as = "parsed", type = "application/json")
pg <- response[["populations"]] %>% bind_rows(lapply(., as.data.frame))
################################### 批量 ###################################
server <- "https://grch37.rest.ensembl.org"
ext <- "/variation/homo_sapiens?pops=1"
body <- list(
  ids = list("rs3762444", "rs284262", "rs655598")
)
json_body <- toJSON(body, auto_unbox = TRUE, pretty = TRUE)
print(json_body)
r <- POST(paste(server, ext, sep = ""), 
          content_type("application/json"), 
          accept("application/json"), 
          body = json_body)
stop_for_status(r)
response <- content(r, as = "parsed", type = "application/json")
pg <- list()
pg <- lapply(response, function(data) {
  bind_rows(lapply(data[["populations"]], as.data.frame))
})