R - Извлечение и анализ каждого экземпляра многострочного текста с разделителями на 2 строки в отдельные строки (.txt to data.frame) - PullRequest
1 голос
/ 13 марта 2020

Я считаю, что это проблема al oop и gregexpr (). Я пытаюсь извлечь / экспортировать многострочный текст из числа стандартизированных экземпляров из числа стандартизированных форм .txt во фрейм данных, где каждый экземпляр представляет собой отдельную строку. До сих пор я мог успешно извлекать строковые данные (хотя алгоритм извлекает немного больше, чем указанные параметры gregexpr ()), но может экспортировать только как .txt в виде единовременной суммы текста.

  1. Как создать фрейм данных из текста извлеченных текстовых файлов, где каждый экземпляр многострочного текста имеет свою собственную строку? (Как только данные в формате data.frame, я знаю, как оттуда экспортировать как xlsx.)
  2. Как извлечь только данные из параметров, которые я установил?

С помощью (в частности, из Бена из комментариев к этому посту ), вот что у меня есть до сих пор:

# Txt Data Format
txt 1 <-
"A. The First:  abcdefg hijklmnop qrstuv wxyz. B. The Second: abcdefg hijklmnop qrstuv wxyz.
    abcdefg hijklmnop qrstuv wxyz. abcdefg hijklmnop qrstuv wxyz abcdefg hijklmnop qrstuv wxyz.
 C. The Third:  abcdefg hijklmnop qrstuv wxyz. D. The Fourth: abcdefg hijklmnop qrstuv wxyz.
    abcdefg hijklmnop qrstuv wxyz. abcdefg hijklmnop qrstuv wxyz abcdefg hijklmnop qrstuv wxyz.
 A. The First:  abcdefg hijklmnop qrstuv wxyz. B. The Second: abcdefg hijklmnop qrstuv wxyz.
    abcdefg hijklmnop qrstuv wxyz. abcdefg hijklmnop qrstuv wxyz abcdefg hijklmnop qrstuv wxyz.
 C. The Third:  abcdefg hijklmnop qrstuv wxyz. D. The Fourth: abcdefg hijklmnop qrstuv wxyz."
    abcdefg hijklmnop qrstuv wxyz. abcdefg hijklmnop qrstuv wxyz abcdefg hijklmnop qrstuv wxyz.

txt 2 <-
"A. The First:  abcdefg hijklmnop qrstuv wxyz. B. The Second: abcdefg hijklmnop qrstuv wxyz.
    abcdefg hijklmnop qrstuv wxyz. abcdefg hijklmnop qrstuv wxyz abcdefg hijklmnop qrstuv wxyz.
 C. The Third:  abcdefg hijklmnop qrstuv wxyz. D. The Fourth: abcdefg hijklmnop qrstuv wxyz.
    abcdefg hijklmnop qrstuv wxyz. abcdefg hijklmnop qrstuv wxyz abcdefg hijklmnop qrstuv wxyz.
 A. The First:  abcdefg hijklmnop qrstuv wxyz. B. The Second: abcdefg hijklmnop qrstuv wxyz.
    abcdefg hijklmnop qrstuv wxyz. abcdefg hijklmnop qrstuv wxyz abcdefg hijklmnop qrstuv wxyz.
 C. The Third:  abcdefg hijklmnop qrstuv wxyz. D. The Fourth: abcdefg hijklmnop qrstuv wxyz."
    abcdefg hijklmnop qrstuv wxyz. abcdefg hijklmnop qrstuv wxyz abcdefg hijklmnop qrstuv wxyz.


#################################
# Directory and Text Extraction #
#################################

dest <- "C:/~"
docs_text <- list.files(path = dest, pattern = "txt",  full.names = TRUE)

## Assumes that all the content I want to extract is between "A." and "C." in 
## the text while ignoring "C." and "D." content.

docs_list <- list.files(path = dest, pattern = "txt",  full.names = TRUE)
docs_doc <- lapply(docs_list, function(i) {
  j <- paste0(scan(i, what = character()), collapse = " ")
  regmatches(j, gregexpr("(?<=A. The First).*?(?=C. The Third)", j, perl=TRUE))
})

lapply(1:length(docs_doc),  function(i) write.table(docs_doc[i], file=paste(docs_list[i], " ", 
" ", sep="."), quote = FALSE, row.names = FALSE, col.names = FALSE, eol = " " ))

Текущий вывод выглядит так, где весь текст в одну строку и захватывает больше, чем просто между "А." и "C.":

Current Output

Желаемый вывод будет выглядеть так, когда многострочный текст между любым экземпляром "A." и "C." извлекается и присваивается одна строка:

Desired Output

Любая помощь, которую вы можете оказать, будет чрезвычайно полезна!

В конечном итоге я пытаюсь разработать модель НЛП, которая могла бы извлекать стандартизированные данные форм из сотен больших PDF-файлов для годичного хранилища. Если этот пост предполагает, что я не думаю о том, как подойти к этой проблеме эффективно / действенно, я открыт для направления.

Заранее спасибо!

Ответы [ 2 ]

2 голосов
/ 13 марта 2020

Regex для спасения.

Во-первых, ваши примерные данные искажены, вот пригодные для использования данные.

txt1 <-
"A. The First:  abcdefg hijklmnop qrstuv wxyz. B. The Second: abcdefg hijklmnop qrstuv wxyz.
    abcdefg hijklmnop qrstuv wxyz. abcdefg hijklmnop qrstuv wxyz abcdefg hijklmnop qrstuv wxyz.
 C. The Third:  abcdefg hijklmnop qrstuv wxyz. D. The Fourth: abcdefg hijklmnop qrstuv wxyz.
    abcdefg hijklmnop qrstuv wxyz. abcdefg hijklmnop qrstuv wxyz abcdefg hijklmnop qrstuv wxyz.
 A. The First:  abcdefg hijklmnop qrstuv wxyz. B. The Second: abcdefg hijklmnop qrstuv wxyz.
    abcdefg hijklmnop qrstuv wxyz. abcdefg hijklmnop qrstuv wxyz abcdefg hijklmnop qrstuv wxyz.
 C. The Third:  abcdefg hijklmnop qrstuv wxyz. D. The Fourth: abcdefg hijklmnop qrstuv wxyz.
    abcdefg hijklmnop qrstuv wxyz. abcdefg hijklmnop qrstuv wxyz abcdefg hijklmnop qrstuv wxyz."
vec <- readLines(textConnection(txt1)) # 'textConnection' to read non-file

Сначала мы объединяем все в одну строку, затем ищем (и разделяем на ) "A.":

paste("A.", Filter(nzchar, strsplit(paste(vec, collapse = ""), "\\bA\\. ")[[1]]))
# [1] "A. The First:  abcdefg hijklmnop qrstuv wxyz. B. The Second: abcdefg hijklmnop qrstuv wxyz.    abcdefg hijklmnop qrstuv wxyz. abcdefg hijklmnop qrstuv wxyz abcdefg hijklmnop qrstuv wxyz. C. The Third:  abcdefg hijklmnop qrstuv wxyz. D. The Fourth: abcdefg hijklmnop qrstuv wxyz.    abcdefg hijklmnop qrstuv wxyz. abcdefg hijklmnop qrstuv wxyz abcdefg hijklmnop qrstuv wxyz. "
# [2] "A. The First:  abcdefg hijklmnop qrstuv wxyz. B. The Second: abcdefg hijklmnop qrstuv wxyz.    abcdefg hijklmnop qrstuv wxyz. abcdefg hijklmnop qrstuv wxyz abcdefg hijklmnop qrstuv wxyz. C. The Third:  abcdefg hijklmnop qrstuv wxyz. D. The Fourth: abcdefg hijklmnop qrstuv wxyz.    abcdefg hijklmnop qrstuv wxyz. abcdefg hijklmnop qrstuv wxyz abcdefg hijklmnop qrstuv wxyz." 
0 голосов
/ 17 марта 2020

Ваш вопрос может быть немного яснее, поскольку я не уверен, следует ли включать строки, начинающиеся с "C. Третий:", или нет. Приведенное ниже решение останавливается прямо перед этой строкой:

data

txt1 <-
  "A. The First:  abcdefg hijklmnop qrstuv wxyz. B. The Second: abcdefg hijklmnop qrstuv wxyz.
    abcdefg hijklmnop qrstuv wxyz. abcdefg hijklmnop qrstuv wxyz abcdefg hijklmnop qrstuv wxyz.
 C. The Third:  abcdefg hijklmnop qrstuv wxyz. D. The Fourth: abcdefg hijklmnop qrstuv wxyz.
    abcdefg hijklmnop qrstuv wxyz. abcdefg hijklmnop qrstuv wxyz abcdefg hijklmnop qrstuv wxyz.
 A. The First:  abcdefg hijklmnop qrstuv wxyz. B. The Second: abcdefg hijklmnop qrstuv wxyz.
    abcdefg hijklmnop qrstuv wxyz. abcdefg hijklmnop qrstuv wxyz abcdefg hijklmnop qrstuv wxyz.
 C. The Third:  abcdefg hijklmnop qrstuv wxyz. D. The Fourth: abcdefg hijklmnop qrstuv wxyz.
    abcdefg hijklmnop qrstuv wxyz. abcdefg hijklmnop qrstuv wxyz abcdefg hijklmnop qrstuv wxyz."
vec <- readLines(textConnection(txt1)) # 'textConnection' to read non-file

answer

Сначала я отмечаю номера строк, начинающиеся с «A. The First» или «C. Третий ". Я разрешаю пробел ("\\s*) между началом элемента (^) и шаблоном.

As <- grep("^\\s*A. The First", vec)
Cs <- grep("^\\s*C. The Third", vec)

Теперь я использую эти номера строк, чтобы найти строки между ними и свернуть их в строки. Обратите внимание, что y - 1 удаляет строку, начинающуюся с "C. Третий ". Если вы хотите сохранить и этот, удалите - 1:

df <- data.frame(
  text = mapply(function(x, y) paste(vec[x:(y - 1)], collapse = "\n"), As, Cs),
  stringsAsFactors = FALSE
)
df
#>                                                                                                                                                                                            text
#> 1  A. The First:  abcdefg hijklmnop qrstuv wxyz. B. The Second: abcdefg hijklmnop qrstuv wxyz.\n    abcdefg hijklmnop qrstuv wxyz. abcdefg hijklmnop qrstuv wxyz abcdefg hijklmnop qrstuv wxyz.
#> 2  A. The First:  abcdefg hijklmnop qrstuv wxyz. B. The Second: abcdefg hijklmnop qrstuv wxyz.\n    abcdefg hijklmnop qrstuv wxyz. abcdefg hijklmnop qrstuv wxyz abcdefg hijklmnop qrstuv wxyz.

Создано в 2020-03-17 пакетом представлением (v0 .3.0)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...