0

pubmed API とやり取りして 100 の出版物に関連付けられた xml ファイルを取得する関数を作成しようとしています。次に、xml ファイルを個別に解析して、各出版物のタイトルと各出版物の要約を取得します。Rentrez パッケージを使用して API と対話し、必要な xml ファイルを正常に取得しました。私は xml パッケージを使用して xml ファイルを解析しており、Xpath 式が必要なデータを取得することを確認しています。実際には、他のフィールド (ジャーナル タイトル、メッシュ用語など) からデータを取得しようとしていますが、ここのこのステップで行き詰っています)

ただし、このデータをデータ フレームに移動するための適切な for ループを作成できませんでした。コードを実行すると、次のエラーが表示されます。

error in $<-.data.frame( *tmp*, "Abstract", value = list("text of abstract"): 置換は 1 行、データは 0

タイトル情報を取得する関数をテストすると (抽象的な情報を取得する式を削除して)、必要なタイトルに関する情報が含まれていない空のデータ フレームが返されます。しかし、エラーメッセージはありません。

pubmed_pa​​rsed("Kandel+Eric", n=2) を実行すると、私の目標は、「ATitle」列の 2 つのタイトルからの文字ベクトルを含むデータ フレームを受け取ることです (タイトル:「レトロトランスポゾンのサイレンシングにおける小さなノンコーディング RNA の役割」哺乳類の脳内」および「ApCPEBのホモログを含む非プリオンドメインであるApCPEB4は、長期的な促進の開始に関与しています」)。そして、2 つのアブストラクトからの文字ベクトルは、「アブストラクト」列に対応して表示されます (アブストラクトの一部:「Piwi 相互作用 RNA (piRNA)、長い間グレムリンに限定されると考えられていました...」、「2 つの薬理学的に異なるタイプのローカルタンパク質合成は、シナプス特異的に必要とされる...")。

library(xml)
library(rentrez)
pubmed_parsed <- function(term, n=100){
    df <- data.frame(ATitle = character(), JTitle = character(), MeshTerms = character(), Abstract = character(), FAuthor = character(), LAuthor = character(), stringsAsFactors = FALSE)
  IdList <- entrez_search(db = "pubmed", term = term, retmode = "xml", retmax = n)
  for (i in 1:n){
    XmlFile <- entrez_fetch(db = "pubmed", id=IdList$ids[i], rettype = "xml", retmode = "xml", parsed=TRUE)
    Parsed <- xmlRoot(XmlFile)
    df$ATitle[i] <- xpathSApply(Parsed, "/PubmedArticleSet/PubmedArticle/MedlineCitation/Article/Title", xmlValue, simplify = FALSE)
    df$Abstract[i] <- xpathSApply(Parsed, "/PubmedArticleSet/PubmedArticle/MedlineCitation/Article/Title", xmlValue, simplify = FALSE)
  }
  df
}
4

1 に答える 1

1

テーブルを取得する 1 つの方法といくつかの提案を次に示します。まず、ダウンロードをループするのではなく、Web 履歴オプションを使用して、すべての結果をまとめてダウンロードします。

ids <- entrez_search(db = "pubmed", term = "Kandel ER", use_history = TRUE)
ids
Entrez search result with 502 hits (object contains 20 IDs and a web_history object)
 Search term (as translated):  Kandel ER[Author] 

doc <- entrez_fetch(db="pubmed", web_history=ids$web_history, rettype="xml", retmax = 3, parsed=TRUE)

次に、記事をノード セットに取得し、欠落しているすべてのタグと複数のタグを処理するクエリを実行します。

articles <- getNodeSet( doc, "//PubmedArticle")
length(articles)
[1] 3
articles[[1]]
<PubmedArticle>
  <MedlineCitation Status="Publisher" Owner="NLM">
    <PMID Version="1">27791114</PMID>
    <DateCreated>
    ...

私は通常、タグが欠落している場合に NA を追加する関数を作成し、コンマを使用して複数のタグを結合します。

xpath2 <-function(x, path, fun = xmlValue, ...){
       y <- xpathSApply(x, path, fun, ...)
     ifelse(length(y) == 0, NA,
        ifelse(length(y) > 1, paste(unlist(y), collapse=", "), y))
}

次に、その関数をノードに適用するだけです(xpathの先頭のドットを使用して、そのノードに相対的です)。これにより、複数のキーワードがカンマ区切りのリストに結合され、キーワードが欠落している記事 3 の NA が含まれます。

sapply(articles, xpath2,  ".//Keyword")
[1] "DNA methylation, behavior, endogenous siRNA, piwi-interacting RNA, transposon"
[2] "Aplysia, CPEB, CPEB4, Long-term facilitation"                                 
[3] NA   

ほとんどの xpath は機能するはずです

sapply(articles, xpath2,  ".//PubDate/Year")
[1] "2016" "2016" "2016"
sapply(articles, xpath2,  ".//ArticleId[@IdType='pmc']")
[1] "PMC5111663" "PMC5075418" NA 

xmlGetAttr必要に応じて使用することもできます

sapply(articles, xpath2,  ".//Article", xmlGetAttr, "PubModel")
[1] "Print-Electronic" "Electronic"       "Electronic"

最後に、data.frame を作成します。

data.frame( 
  ATitle = sapply(articles, xpath2,  ".//ArticleTitle"),
  JTitle = sapply(articles, xpath2,  ".//Journal/Title"),
Keywords = sapply(articles, xpath2,  ".//Keyword"),
 Authors = sapply(articles, xpath2,  ".//Author/LastName"),
Abstract = sapply(articles, xpath2,  ".//AbstractText"))

MeSH 用語に何が起こったのかはわかりませんが、ダウンロードしたいくつかの例にキーワードしか表示されません。また、最初の著者と最後の著者を取得する方法はおそらくいくつかあります。姓とイニシャルの両方を取得し (両方が常に存在すると仮定)、イニシャルの前のコンマを置き換えて作成者文字列を取得できます。次に、それを分割して最初と最後の著者を取得するか、最初の 3 つを以下に出力します。

au <- sapply(articles, xpath2,  ".//Author/LastName|.//Author/Initials")
au <- gsub(",( [A-Z]+,?)", "\\1", au)
authors_etal <- function(x, authors=3, split=", *"){
   y <- strsplit(x, split)
   sapply(y, function(x){
      if(length(x) > (authors + 1))  x <- c(x[1:authors], "et al.")
      paste(x, collapse=", ")
   })
}

authors_etal(au)
[1] "Nandi S, Chandramohan D, Fioriti L, et al."
[2] "Lee SH, Shim J, Cheong YH, et al."         
[3] "Si K, Kandel ER" 
于 2016-12-02T23:23:24.337 に答える