Как извлечь определенные c частей грязных PDF-файлов в R? - PullRequest
1 голос
/ 06 августа 2020

Мне нужно извлечь определенные c части большого корпуса PDF-документов. PDF-файлы представляют собой большие и беспорядочные отчеты, содержащие всевозможную цифровую, буквенную c и другую информацию. Файлы имеют разную длину, но имеют единое содержимое и разделы. В документах есть Оглавление с названиями разделов в них. Например,

Table of Content:

Item 1. Business                                                                            1
Item 1A. Risk Factors                                                                       2
Item 1B. Unresolved Staff Comments                                                          5
Item 2. Properties                                                                          10
Item N........

..........text I do not care about...........

Item 1A. Risk Factors 

.....text I am interested in getting.......

(section ends)

Item 1B. Unresolved Staff Comments

..........text I do not care about...........

У меня нет проблем с их чтением и анализом в целом, но мне нужно вытащить только текст между «Элемент 1A. Факторы риска» и «Пункт 1B. Нерешенные комментарии сотрудников» . Я использовал pdftools, tm, quanteda и пакет readtext Это часть кода, которую я использую для чтения моих документов. Я создал каталог, в который поместил свои файлы PDF, и назвал его «PDF» и другой каталог, в который R поместит преобразованные в файлы «.txt».

pdf_directory <- paste0(getwd(), "/PDF")
txt_directory <- paste0(getwd(), "/Texts")

Затем я создаю список файлов, используя «list». files "функция.

files <- list.files(pdf_directory, pattern = ".pdf", recursive = FALSE, 
                    full.names = TRUE)
files

После этого я go создаю функцию, которая извлекает имена файлов.

extract <- function(filename) {
  print(filename)
  try({
    text <- pdf_text(filename)
  })
  f <- gsub("(.*)/([^/]*).pdf", "\\2", filename)
  write(text, file.path(txt_directory, paste0(f, ".txt")))
}

for (file in files) {
  extract(file)
}

После этого шага я застреваю и не знаю, как действовать. Я не уверен, следует ли мне пытаться извлечь интересующий раздел при чтении данных, поэтому, я полагаю, мне придется бороться с фрагментом, в котором я создаю функцию - f <- gsub("(.*)/([^/]*).pdf", "\\2", filename)? Прошу прощения за такие вопросы, но я сам учусь. Я также пробовал использовать следующий код только для одного файла вместо корпуса:

start <- grep("^\\*\\*\\* ITEM 1A. RISK FACTORS", text_df$text) + 1

stop <- grep("^ITEM 1B. UNRESOLVED STAFF COMMENTS", text_df$text) - 1

lines <- raw[start:stop]

scd <- paste0(".*",start,"(.*)","\n",stop,".*")  
gsub(scd,"\\1", name_of_file)

, но это мне никак не помогло.

1 Ответ

1 голос
/ 07 августа 2020

Я действительно не понимаю, почему вы должны сначала записывать файлы в текстовый текст, поэтому я сделал все за один go.

Что меня немного сбило с толку, так это то, что в ваших шаблонах много пробелы. Вы можете сопоставить их с регулярным выражением \\s+

library(stringr)
files <- c("https://corporate.exxonmobil.com/-/media/Global/Files/investor-relations/investor-relations-publications-archive/ExxonMobil-2016-Form-10-K.pdf",
           "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf")


relevant_l <- lapply(files, function(file) {
  
  # print status message
  message("processing: ", basename(file))
  
  lines <- unlist(stringr::str_split(pdftools::pdf_text(file), "\n"))
  start <- stringr::str_which(lines, "ITEM 1A.\\s+RISK FACTORS")
  end <- stringr::str_which(lines, "ITEM 1B.\\s+UNRESOLVED STAFF COMMENTS")
  
  # cover a few different outcomes depending on what was found
  if (length(start) == 1 & length(end) == 1) {
    relevant <- lines[start:end]
  } else if (length(start) == 0 | length(end) == 0) {
    relevant <- "Pattern not found"
  } else {
    relevant <- "Problems found"
  }
  
  return(relevant)
})
#> processing: ExxonMobil-2016-Form-10-K.pdf
#> processing: dummy.pdf

names(relevant_l) <- basename(files)
sapply(relevant_l, head)
#> $`ExxonMobil-2016-Form-10-K.pdf`
#> [1] "ITEM 1A.           RISK FACTORS\r"                                                                                                   
#> [2] "ExxonMobil’s financial and operating results are subject to a variety of risks inherent in the global oil, gas, and petrochemical\r" 
#> [3] "businesses. Many of these risk factors are not within the Company’s control and could adversely affect our business, our financial\r"
#> [4] "and operating results, or our financial condition. These risk factors include:\r"                                                    
#> [5] "Supply and Demand\r"                                                                                                                 
#> [6] "The oil, gas, and petrochemical businesses are fundamentally commodity businesses. This means ExxonMobil’s operations and\r"         
#> 
#> $dummy.pdf
#> [1] "Pattern not found"

Я бы вернул результаты в виде списка, а затем использовал бы исходные имена файлов для именования элементов списка. Дайте мне знать, если у вас возникнут вопросы. Я использую пакет stringr, поскольку он работает быстро и последовательно со строками. Но команды str_which и grep практически одинаковы.

...