Как улучшить код R для извлечения идентификаторов из структурированного текстового файла - PullRequest
0 голосов
/ 04 сентября 2018

Моя цель - проанализировать структурированный текстовый файл и извлечь 4 уникальных идентификатора во фрейм данных R.

В качестве первого шага я запустил

c <- read_lines("minex_cochrane.txt") 

Тогда, учитывая символьный вектор c, где каждый элемент является линией.

c <- c("Record #1 of 3", "ID: CN-00966682", "TI: A multi-center, randomized controlled trial of a group psychological intervention for psychosis with comorbid cannabis dependence over the early course of illness", 
    "SO: Schizophrenia research", "YR: 2013", "VL: 143", "NO: 1", 
    "CC: Drugs and Alcohol", "PG: 138‐142", "PM: PUBMED 23187069", 
    "PT: Journal Article; Multicenter Study; Randomized Controlled Trial", 
    "DOI: 10.1016/j.schres.2012.10.018", "US: https://www.cochranelibrary.com/central/doi/10.1002/central/CN-00966682/full", 
    "", "", "Record #2 of 3", "ID: CN-00917992", "TI: Effectiveness of a self-guided web-based cannabis treatment program: randomized controlled trial", 
    "SO: Journal of medical internet research", "YR: 2013", "VL: 15", 
    "NO: 2", "PG: e26", "PM: PUBMED 23470329", "XR: EMBASE 23470329", 
    "PT: Journal Article; Randomized Controlled Trial; Research Support, Non‐U.S. Gov't; Research Support, U.S. Gov't, Non‐P.H.S.", 
    "KY: Adult; Australia; Female; Health Behavior; Humans; Internet; Male; Marijuana Abuse [psychology, *therapy]; Outcome Assessment (Health Care); Self Care; Telemedicine [*methods]; Therapy, Computer‐Assisted; Treatment Outcome; Young Adult", 
    "DOI: 10.2196/jmir.2256", "US: https://www.cochranelibrary.com/central/doi/10.1002/central/CN-00917992/full", 
    "", "", "")

Следующее обнаруживает, а затем очищает мои нужные уникальные идентификаторы.

library(stringr)
id_l <- str_detect(c, "ID: ")
id_vec <- c[id_l == TRUE]
id <- str_replace(id_vec, "ID: ", "")

pmid_l <- str_detect(c,"PM: PUBMED")
pmid_vec <- c[pmid_l == TRUE]
pmid <- str_replace(pmid_vec, "PM: PUBMED ", "")
cs <- cbind(id, pmid)

Получение следующего вывода по желанию.

> cs
     id            pmid      
[1,] "CN-00966682" "23187069"
[2,] "CN-00917992" "23470329"

Однако это кажется слишком громоздким. Я хотел бы улучшить свой код, чтобы сделать это более компактным и эффективным способом для облегчения анализа большого файла.

Ответы [ 3 ]

0 голосов
/ 04 сентября 2018

Более кратким было бы применить str_extract() напрямую:

library(stringr)
library(magrittr)
cs <- data.frame(
  id = str_extract(c, '(?<=^ID: ).*') %>% .[!is.na(.)],
  pmid = str_extract(c, '(?<=PUBMED ).*') %>% .[!is.na(.)]
)

В результате:

           id     pmid
1 CN-00966682 23187069
2 CN-00917992 23470329

Предупреждение:

Это предполагает почти идеальную согласованность / регулярность ваших данных.

EDIT

Можно упростить, используя na.omit(), о котором я забыл (кредит Роланду):

cs <- data.frame(
  id = na.omit(str_extract(c, '(?<=^ID: ).*')),
  pmid = na.omit(str_extract(c, '(?<=PUBMED ).*'))
)
0 голосов
/ 04 сентября 2018

Вы могли бы использовать регулярное выражение с или в условии просмотра:

matrix(na.omit(str_extract(c, "(?<=ID: |PM: PUBMED )(.+)")),
       ncol = 2, byrow = TRUE)
#     [,1]          [,2]      
#[1,] "CN-00966682" "23187069"
#[2,] "CN-00917992" "23470329
0 голосов
/ 04 сентября 2018

может быть как то так?

Код предполагает, что для каждого идентификатора: xyz есть PM: xyz: следующий за следующим идентификатором: xyz.

ids= c[which(grepl("^ID: |^PM: ", c))] # find and select each element starting either with "ID: " or "PM: "
df = matrix(data = ids, nrow = length(ids)/2, ncol = 2, byrow = T) # transforme the vector in a matrix, assuming that the order is allways ID: PM: (so for each ID-entry there has to be a PM entry too) 
df = apply(df,2,function(f) gsub("ID: |PM: |PUBMED ", "", f)) # remove all ID: , PM: , PUBMED from all of the strings
df
...