用户定义函数在 dplyr 管道中不起作用

User Defined Function not working in dplyr pipe

我有一个包含蛋白质登录号的数据集 (DataGranulomeTidy)。我在 r 中写了一个函数 (extractInfo) 来 scrape 来自 ncbi 网站的那些蛋白质的一些信息。当我在一个简短的“for”循环中 运行 它时,该函数按预期工作。

DataGranulomeTidy <- tibble(GIaccessionNumber = c("29436380", "4504165", "17318569"))

extractInfo <- function(GInumber){
    tempPage <- readLines(paste("https://www.ncbi.nlm.nih.gov/sviewer/viewer.fcgi?id=", GInumber, "&db=protein&report=genpept&conwithfeat=on&withparts=on&show-cdd=on&retmode=html&withmarkup=on&tool=portal&log$=seqview&maxdownloadsize=1000000", sep = ""), skipNul = TRUE)
    tempPage  <- base::paste(tempPage, collapse = "")
    Accession <- str_extract(tempPage, "(?<=ACCESSION).{3,20}(?=VERSION)")
    Symbol    <- str_extract(tempPage, "(?<=gene=\").{1,20}(?=\")")
    GeneID    <- str_extract(tempPage, "(?<=gov/gene/).{1,20}(?=\">)")
    out       <- paste(Symbol, Accession, GeneID, sep = "---")
    return(out)
}


for(n in 1:3){
    print(extractInfo(GInumber = DataGranulomeTidy$GIaccessionNumber[n]))
}
 [1] "MYH9---   AAH49849---4627"
 [1] "GSN---   NP_000168---2934"
 [1] "KRT1---   NP_006112---3848"

当我在 dplyr 管道中使用相同的功能时,我无法正常工作,我无法弄清楚原因。

 > DataGranulomeTidy %>% mutate(NewVar = extractInfo(.$GIaccessionNumber))
 Error in file(con, "r") : argumento 'description' inválido

此时我可以通过使用“for”运算符在不使用“管道”运算符的情况下使事情正常进行,但我非常想了解为什么该函数在 dplyr 管道中不起作用。

是你的UDF不能处理vector的原因。

vectorized_extractInfo <- Vectorize(extractInfo, "GInumber")

DataGranulomeTidy %>% 
  mutate(NewVar = vectorized_extractInfo(GIaccessionNumber))

正如@cuttlefish44 已经指出的那样,问题是您的乐趣不是矢量化的乐趣。我的方法使用 purrr::map_chr。另一种选择是使用 dplyr::rowwise:

library(tidyverse)

DataGranulomeTidy <- tibble(GIaccessionNumber = c("29436380", "4504165", "17318569"))

extractInfo <- function(GInumber){
  tempPage <- readLines(paste("https://www.ncbi.nlm.nih.gov/sviewer/viewer.fcgi?id=", GInumber, "&db=protein&report=genpept&conwithfeat=on&withparts=on&show-cdd=on&retmode=html&withmarkup=on&tool=portal&log$=seqview&maxdownloadsize=1000000", sep = ""), skipNul = TRUE)
  tempPage  <- base::paste(tempPage, collapse = "")
  Accession <- str_extract(tempPage, "(?<=ACCESSION).{3,20}(?=VERSION)")
  Symbol    <- str_extract(tempPage, "(?<=gene=\").{1,20}(?=\")")
  GeneID    <- str_extract(tempPage, "(?<=gov/gene/).{1,20}(?=\">)")
  out       <- paste(Symbol, Accession, GeneID, sep = "---")
  return(out)
}

DataGranulomeTidy %>% mutate(NewVar = map_chr(GIaccessionNumber, extractInfo))
#> # A tibble: 3 x 2
#>   GIaccessionNumber NewVar                    
#>   <chr>             <chr>                     
#> 1 29436380          MYH9---   AAH49849---4627 
#> 2 4504165           GSN---   NP_000168---2934 
#> 3 17318569          KRT1---   NP_006112---3848

reprex package (v0.3.0)

于 2020-04-17 创建

NCBI 查询有一个 rentrez 包,例如:

library(rentrez)

protein <- entrez_summary("protein", id = 29436380)
protein$caption
# [1] "AAH49849"

links <- entrez_link(dbfrom = "protein", id = 29436380, db = "gene")
links$links$protein_gene
# [1] "4627"

gene <- entrez_summary("gene", id = links$links$protein_gene)
gene$name
# [1] "MYH9"

将其包装成一个函数,那么我们就不需要搞乱正则表达式