Пользовательская функция не работает в трубе dplyr - PullRequest
5 голосов
/ 17 апреля 2020

У меня есть набор данных с номерами доступа белков (DataGranulomeTidy). Я написал функцию (extractInfo) в r, чтобы удалить некоторую информацию об этих белках с сайта ncbi. Функция работает, как и ожидалось, когда я запускаю ее в коротком «для» l oop.

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

На данный момент я мог бы заставить вещи работать без использования оператора "pipe" с помощью оператора "for", но я бы очень хотел понять, почему функция не работает в труба dplyr.

Ответы [ 3 ]

4 голосов
/ 17 апреля 2020

Это причина того, что ваш UDF не может обработать вектор.

vectorized_extractInfo <- Vectorize(extractInfo, "GInumber")

DataGranulomeTidy %>% 
  mutate(NewVar = vectorized_extractInfo(GIaccessionNumber))
3 голосов
/ 17 апреля 2020

Как уже указывал @ 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

, созданный в 2020-04-17 пакетом Представить (v0.3.0)

0 голосов
/ 17 апреля 2020

Существует пакет rentrez для запросов NCBI, например:

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"

Оберните это в функцию, тогда нам не нужно возиться с регулярное выражение .

...