如何优化R中批量获取PubChem BioAssay活性数据的代码?
代码优化建议
1. 批量查询替代单CID循环(核心优化)
PubChem的SDQ支持批量CID查询,不用逐个发起请求,直接把一批CID放进查询条件里,能大幅减少HTTP请求次数,这是提升速度最关键的点。建议每次批量处理50-100个CID(避免单次请求过大被限流)。
示例代码:
library(data.table) library(tidyverse) # 假设你的df包含11500个CID df <- data.table(Compound = sample(1:100000, 11500)) # 拆分CID为批次,每批次100个 cid_batches <- split(df$Compound, ceiling(seq_along(df$Compound)/100)) # 存储结果的列表 result_list <- list() for (batch in cid_batches) { # 把批次里的CID转成符合SDQ格式的字符串 cid_str <- paste0('"', paste(batch, collapse = '","'), '"') url <- paste0( 'https://pubchem.ncbi.nlm.nih.gov/sdq/sdqagent.cgi?infmt=json&outfmt=csv&query=', URLencode('{"download":"*","collection":"bioactivity","where":{"ands":[{"cid":{"in":[', cid_str, ']}}],"order":["acvalue,asc"],"start":1,"limit":10000000,"nullatbottom":1}}') ) # 读取数据并过滤活性为Active的行 batch_data <- fread(url) %>% filter(activity == "Active") result_list[[length(result_list)+1]] <- batch_data # 加小延迟避免请求过于频繁被限流 Sys.sleep(0.5) } # 合并所有批次的结果 final_data <- bind_rows(result_list)
2. 并行处理进一步提速
如果你的机器有多核CPU,可以用并行工具同时处理多个批次,把等待请求响应的时间利用起来。这里用furrr包(tidyverse风格的并行工具):
library(furrr) # 设置并行工作核心数,比如用4核 plan(multisession, workers = 4) # 用future_map替代循环处理批次 result_list <- future_map(cid_batches, function(batch) { cid_str <- paste0('"', paste(batch, collapse = '","'), '"') url <- paste0( 'https://pubchem.ncbi.nlm.nih.gov/sdq/sdqagent.cgi?infmt=json&outfmt=csv&query=', URLencode('{"download":"*","collection":"bioactivity","where":{"ands":[{"cid":{"in":[', cid_str, ']}}],"order":["acvalue,asc"],"start":1,"limit":10000000,"nullatbottom":1}}') ) # 捕获请求失败的情况,避免中断整个流程 batch_data <- tryCatch({ fread(url) %>% filter(activity == "Active") }, error = function(e) { message(paste("批次处理失败:", e$message)) return(tibble()) }) Sys.sleep(0.3) return(batch_data) }) final_data <- bind_rows(result_list)
3. 避免循环中累积数据的低效操作
原来的代码每次用bind_rows(data_bioassays, data_x),会不断复制整个数据框,数据量越大越慢。改用列表存储每个批次的结果,最后一次性合并,这是R处理批量数据的标准高效做法。
4. 增加请求容错机制
网络波动或PubChem限流可能导致请求失败,用tryCatch捕获错误,避免整个循环中断,同时记录失败的批次方便后续重试。
5. 优化请求参数
- 去掉
downloadfilename参数,这个是下载时的文件名,直接请求数据不需要,可减少URL长度。 - 用
URLencode处理查询字符串,避免特殊字符导致请求错误。 - 添加合理的
Sys.sleep延迟,官方建议请求间隔不小于0.3秒,避免短时间内发送大量请求被限流。
6. 预处理CID列表
提前检查CID是否为有效正整数,过滤掉无效值,减少不必要的请求。
内容的提问来源于stack exchange,提问作者xsrt
相关产品推荐
相关产品推荐

