6

I have a dataset with proteins accession numbers (DataGranulomeTidy). I have written a function (extractInfo) in r to scrape some information of those proteins from the ncbi website. The function works as expected when I run it in a short "for" loop.

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"

When I use the same function in a dplyr pipe I doesn't work and I can't figure our why.

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

At this point I could make things work without using the "pipe" operator by using the "for" operator but I would like so much to understand why the function does not work in the dplyr pipe.

netlak
  • 97
  • 5
  • I have corrected a copy/paste error on the URL – netlak Apr 17 '20 at 09:24
  • you don't need `base::` prefix, unless you mask `paste`, which is something that you should start fixing from – jangorecki Apr 17 '20 at 09:25
  • 1
    paste is masked by the package "BiocGenerics" I have in my instance. I think they work the same but just to be sure I used base:: Thanks! – netlak Apr 17 '20 at 09:29

3 Answers3

4

It is the cause that your UDF can't treat vector.

vectorized_extractInfo <- Vectorize(extractInfo, "GInumber")

DataGranulomeTidy %>% 
  mutate(NewVar = vectorized_extractInfo(GIaccessionNumber))
cuttlefish44
  • 6,586
  • 2
  • 17
  • 34
3

As @cuttlefish44 already pointed out, the problem is that your fun is not a vectorized fun. My approach uses purrr::map_chr. Another option would be to use 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

Created on 2020-04-17 by the reprex package (v0.3.0)

stefan
  • 90,330
  • 6
  • 25
  • 51
1

There is a rentrez package for NCBI queries, for example:

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"

Wrap this up into a function, then we don't need to mess about with regex.

zx8754
  • 52,746
  • 12
  • 114
  • 209