Извлечение элементов из текстовых файлов в R

Я пытаюсь заняться анализом текста в R. У меня есть текстовый файл со следующей структурой.

HD  A YEAR Oxxxx
 WC 244 words
 PD 28 February 2018
 SN XYZ
 SC hydt
 LA English
 CY Copyright 2018 

 LP Rio de Janeiro, Feb 28



TD
   With recreational cannabis only months away from legalization in Canada, companies are racing to
   prepare for the new market. For many, this means partnerships, supply agreements,

Я хочу извлечь следующие элементы (PD и TD) в R и сохранить в таблицу.

Я пробовал это, но я не могу понять это правильно.

Извлечь PD

library(stringr)
library(tidyverse)

pd <- unlist(str_extract_all(txt, "\\bPD\\b\t[0-9]+?\\s[A-Za-z]+?\\s[0-9]+\\s"))
pd <- str_replace_all(pd, "\\bPD\\b\t", "")
if (length(pd) == 0) {
  pd <- as.character(NA)
}
pd <- str_trim(pd)
pd <- as.Date(strptime(pd, format = "%d %B %Y"))

Извлечь TD

td <- unlist(str_extract_all(txt, "\\bTD\\b[\\t\\s]*?.+?\\bCO\\b"))
td <- str_replace_all(td, "\\bTD\\b[\\t\\s]+?", "")
td <- str_replace_all(td, "\\bCO\\b", "")
td <- str_replace_all(td, "\\s+", " ")
if (length(td) == 0) {
  td <- as.character(NA)

Я хочу таблицу следующим образом, пожалуйста:

PD                        TD
28 February 2018          With recreational cannabis only months away from 
                          legalization in Canada, companies are racing to
                          prepare for the new market. For many, this means 
                          partnerships, supply agreements, Production hit a 
                          record 366.5Mt

Любая помощь будет оценена по достоинству. Спасибо


person Beginner    schedule 04.04.2018    source источник


Ответы (1)


[Мне пришлось добавить несколько символов в конец вашего набора данных, который я вывел из ваших регулярных выражений:

txt <- "HD  A YEAR Oxxxx
 WC 244 words
 PD 28 February 2018
 SN XYZ
 SC hydt
 LA English
 CY Copyright 2018 

 LP Rio de Janeiro, Feb 28



TD
   With recreational cannabis only months away from legalization in Canada, companies are racing to
   prepare for the new market. For many, this means partnerships, supply agreements,
CO ...further stuff"

Грязный

Грязное решение ваших проблем, вероятно:

  • Для поля даты исправьте либо регулярное выражение, которое ожидает не табуляцию, а произвольный пробел после текста PD. Например. \\bPD\\b [0-9]+?\\s[A-Za-z]+?\\s[0-9]+\\s" у меня работает.
  • Для поля TD сделайте регулярное выражение многострочным, используя параметр dotall=: (см. ?stringr::regex)

    td <- unlist(str_extract_all(txt, regex("\\bTD\\b[\\t\\s]*?.+?\\bCO\\b", dotall=TRUE)))
    

Может быть, более короткие регулярные выражения лучше?

Тем не менее, я бы рекомендовал вам фиксировать характеристики вашего входного формата только настолько детально, насколько это необходимо. Например, я бы не стал проверять формат даты с помощью регулярного выражения. Просто найдите "^ PD.*" и дайте R попытаться проанализировать результат. Он все равно будет жаловаться, если он не соответствует.

Чтобы отфильтровать текстовый блок, который начинается с нескольких пробелов, например, после маркера TD, вы можете использовать параметр multiline=, чтобы использовать ^ для соответствия началу каждой (не только первой) строки. Например.

str_extract_all(txt, regex("^TD\\s+(^\\s{3}.*\\n)+", multiline = TRUE))

(обратите внимание, что класс регулярного выражения \s содержит \n, поэтому мне не нужно указывать это явно после сопоставления строки TD)

Будьте осторожны, если поля отсутствуют

Наконец, ваш текущий подход может назначать неверные даты тексту, если одно из полей TD или PD отсутствует во входных данных! В этом может помочь цикл for в сочетании с readLines вместо сопоставления регулярных выражений:

person akraf    schedule 04.04.2018
comment
Привет @akraf - спасибо за помощь. Однако я не могу получить желаемые результаты. Есть ли способ отправить вам мой рабочий R-скрипт для ознакомления. Спасибо - person Beginner; 05.04.2018