Одновременное извлечение нескольких фраз из нескольких PDF-файлов с помощью R

У меня есть список путей pdf в одной таблице, и я пытаюсь повторить приведенные ниже команды для остальных перечисленных pdf. В основном я конвертирую файл pdf в текст только для первой страницы файла, а затем использую команду keyword_search для запуска поиска по определенным фразам на этой странице. Я могу успешно выполнить это для одного файла за раз, но у меня есть 281 файл. Что мне не хватает??

ОДИН ФАЙЛ PDF

    my.file<-"//.../cover-letter.pdf"
    my.page<-pdf_text(my.file)[1] %>% as.character()
    my.result<-keyword_search(my.page, keyword = c('reason','not being marketed', 'available for sale', 'withdrawn from sale', 'commercial distribution', 'target date'), ignore_case = TRUE)
    my.result$Cover_Letter<-my.file
    
    my.result<-select(my.result, -5)
    result<-merge(TotNoMark_clean, my.result, by = "Cover_Letter", all.x = TRUE)

НЕСКОЛЬКО ФАЙЛОВ PDF: НЕУДАЧНАЯ ПОПЫТКА


DF<-as.data.frame(TotNoMark_clean)
file.names<-DF$Cover_Letter

for(i in 1:length(file.names)){
  {pdf_pages<-pdf_text(file.names[i])[1]
  pdf_result<-keyword_search(pdf_pages, keyword = c('reason','not being marketed', 'available for sale', 'withdrawn from sale', 'commercial distribution', 'target date'))
  pdf_result$Cover_Letter<-file.names[i]
  if (!nrow(pdf_result)) {next}
  }
  Result<<-pdf_result
}
Result<-select(Result, -5)
Result<-merge(DF, Result, by = "Cover_Letter", all.x = TRUE)

Я получаю следующее сообщение об ошибке:

    "Error in `$<-.data.frame`(`*tmp*`, "Cover_Letter", value = "//cover-letters/***.pdf") : 
  replacement has 1 row, data has 0"

2 ответа

В настоящее время ваш результат никогда не сохраняет прошлые итерации только самый последний элемент, даже если вы используете оператор области видимости,<<-, так как вы не используете список и не увеличиваете свой объект в цикле (последнее не рекомендуется). И на самом деле вам нужно<<- поскольку forцикл выполняется не на локальных, а на глобальных объектах. Если у вашего последнего элемента были пустые строки,nextприведет к тому, что Результат будет пустым.

Рассмотрите возможность создания списка фреймов данных для последующего запуска bind_rows внешний цикл для окончательного вывода:

DF <- as.data.frame(TotNoMark_clean)
# INITIALIZE EMPTY LIST
Result_dfs <- vector(mode="list", length=nrow(DF))

for(i in seq_along(DF$Cover_Letter)) {
  pdf_pages <- pdf_text(DF$Cover_Letter[i])[1]
  pdf_result <- keyword_search(pdf_pages, 
                               keyword = c('reason','not being marketed', 'available for sale', 
                                           'withdrawn from sale', 'commercial distribution', 
                                           'target date'))
  pdf_result$Cover_Letter <- DF$Cover_Letter[i]

  # SAVE TO LIST REGARDLESS OF NROWs 
  Result_dfs[i] <- pdf_result
}

# BIND ALL DFs TOGETHER AND SELECT LAST FIVE COLS
Result <- dplyr::select(dplyr::bind_rows(Result_dfs), -5)

# MERGE TO ORIGINAL
Result <- merge(DF, Result, by = "Cover_Letter", all.x = TRUE)

В качестве альтернативы используйте lapply чтобы избежать учета инициализации списка и присвоения элементов списка:

DF <- as.data.frame(TotNoMark_clean)

Result_dfs <- lapply(DF$Cover_Letter, function(f) {
    pdf_pages <- pdf_text(f)[1]
    pdf_result <- keyword_search(pdf_pages, 
                                 keyword = c('reason','not being marketed', 'available for sale', 
                                             'withdrawn from sale', 'commercial distribution', 
                                             'target date'))
    pdf_result$Cover_Letter <- f
    return(pdf_result)
})

# BIND ALL DFs TOGETHER AND SELECT LAST FIVE COLS
Result <- dplyr::select(dplyr::bind_rows(Result_dfs), -5)

# LEFT JOIN TO ORIGINAL
Result <- dplyr::left_join(DF, Result, by="Cover_Letter")

После того, как я проверил, находятся ли соответствующие поля в правильном классе, вот что я в итоге сделал, и это сработало:

PhrasePull<-function(){
DF<-as.data.frame(TotNoMark_clean)
file.names<-DF$Cover_Letter
Result<-data.frame()
for(i in 1:length(file.names)){
    {pdf_pages<-pdf_text(file.names[i])[1]
    pdf_result<-keyword_search(pdf_pages, keyword = c('reason','not being marketed', 'has not marketed', 'will be able to market', 'will market', 'is not marketing', 'available for sale', 'withdrawn from sale', 'commercial marketing', 'commercial distribution', 'target date', 'will be available', 'marketing of this product has been started', 'commercially marketed', 'discontinued', 'launch.', 'not currently marketed', 'unable to market', 'listed in the active section of the Orange Book', 'not currently being manufactured or marketed'), ignore_case = TRUE)
    if (!nrow(pdf_result)) {next}
    pdf_result$Cover_Letter<-file.names[i]
    }
  Result <- bind_rows(Result, pdf_result)
  }
output<<-merge(DF, Result, by = "Cover_Letter", all.x = TRUE)
}
Другие вопросы по тегам