【问题标题】:Error handling when using pdftools in a loop在循环中使用 pdftools 时的错误处理
【发布时间】:2020-10-15 00:23:10
【问题描述】:

我正在尝试从多个 pdf 文件中提取某些表格,但并非所有文件都有该表格。 即使第一个文件不包含某个表,如何使用 trycatch 或类似方法跳过并继续下一个文件?

library(pdftools)
library(tidyverse)

url <- c("https://www.computershare.com/News/Annual%20Report%202019.pdf?2",
         "https://www.annualreports.com/HostedData/AnnualReportArchive/a/LSE_ASOS_2018.PDF")

raw_text <- map(url, pdf_text)

clean_table1 <- function(raw) {
  
  raw <- map(raw, ~ str_split(.x, "\\n") %>% unlist())
  raw <- reduce(raw, c)
  
  table_start <- stringr::str_which(tolower(raw), "twenty largest shareholders")
  table_end <- stringr::str_which(tolower(raw), "total")
  table_end <- table_end[min(which(table_end > table_start))]
  
  table <- raw[(table_start + 3 ):(table_start + 25)]
  table <- str_replace_all(table, "\\s{2,}", "|")
  text_con <- textConnection(table)
  data_table <- read.csv(text_con, sep = "|")
  #colnames(data_table) <- c("Name", "Number of Shares", "Percentage")
  data_table
}

shares <- map_df(raw_text, clean_table1) 

我在尝试运行时遇到以下错误。

Error in (table_start + 3):(table_start + 25) : argument of length 0
In addition: Warning message:
In min(which(table_end > table_start)) :
  no non-missing arguments to min; returning Inf

【问题讨论】:

  • 哪里出错了?
  • @r2evans 在表提取期间Error in (table_start + 3):(table_start + 25) : argument of length 0 In addition: Warning message: In min(which(table_end &gt; table_start)) : no non-missing arguments to min; returning Inf
  • if (!length(table_start) &amp;&amp; !length(table_end)) return(); 紧接在 table &lt;- ... 之前会抢占该错误。我不确定它为什么会发生,但至少你可以在它发生之前走出去。意识到在这种情况下您正在返回 NULL(我认为这没有问题,尽管调用环境必须处理它)。

标签: r error-handling try-catch pdftools


【解决方案1】:

您可以检查 lengthtable_startreturn NULL 是否为 0,因此在使用 map_df 时,这些记录会自动折叠,您将拥有一个组合数据框。

library(tidyverse)

clean_table1 <- function(raw) {
  
  raw <- map(raw, ~ str_split(.x, "\\n") %>% unlist())
  raw <- reduce(raw, c)
  
  table_start <- stringr::str_which(tolower(raw), "twenty largest shareholders")
  if(!length(table_start)) return(NULL)
  table_end <- stringr::str_which(tolower(raw), "total")
  table_end <- table_end[min(which(table_end > table_start))]
  
  table <- raw[(table_start + 3 ):(table_start + 25)]
  table <- str_replace_all(table, "\\s{2,}", "|")
  text_con <- textConnection(table)
  data_table <- read.csv(text_con, sep = "|")
  #colnames(data_table) <- c("Name", "Number of Shares", "Percentage")
  data_table
}

shares <- map_df(raw_text, clean_table1)

【讨论】:

  • 这似乎有效,但是当我在其他文件上尝试时,我收到了这个错误Error in read.table(file = file, header = header, sep = sep, quote = quote, : more columns than column names。我想有些文件有更多列的表?我如何对此进行错误处理?
  • 不看数据很难判断。但是,我有两个猜测可以考虑。只读 3 列 data_table &lt;- read.csv(text_con, sep = "|")[1:3]。如果超过 3 列,则返回 NULLif(ncol(data_table) &gt; 3) return(NULL).
猜你喜欢
  • 2021-05-10
  • 1970-01-01
  • 2011-11-30
  • 1970-01-01
  • 2013-05-18
  • 2018-04-06
  • 2019-10-28
  • 2015-02-07
  • 1970-01-01
相关资源
最近更新 更多