You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用R的pdftools读取PDF表格时,如何解决备注列引发的列偏移问题?

解决PDF表格读取的列偏移与多行合并问题

问题背景

用R的pdftools编写的PDF表格读取函数,基础读取功能正常,但遇到两个核心问题:

  1. 表格存在仅部分填充的备注列,导致带备注的行数据出现列偏移(如当前输出第8行、第15行的备注内容错位到最后一列);
  2. 部分长项目名称被拆分为多行,进一步加剧数据错位(如“Fair-value movement of investment properties”被拆成两行)。

核心解决方案

放弃依赖空格拆分的不可靠方式,改用固定列位置截取(PDF表格列是绝对对齐的,有固定起始/结束位置),同时先合并拆分的多行项目名称,再处理列数据。

具体实现代码

# 加载所需包
library(pdftools)
library(stringr)

# 目标PDF链接
url <- "https://www.rymanhealthcare.co.nz/hubfs/Investor%20Centre/Financial/Half%20year%20results%202022/Ryman%20Healthcare%20Limited%20-%20Announcement%20Numbers%20and%20financial%20statements%20-%2030%20September%202022.pdf"
pdf_data <- pdf_text(url)

# 修正后的PDF表格读取函数
scrape_pdf_fixed <- function(pdf_text, table_number, column_positions, column_names, first_row, last_row) {
  # 提取目标页码的文本并拆分行
  page_text <- pdf_text[table_number]
  page_lines <- str_split(page_text, "\n")[[1]] %>% trimws()
  # 过滤空行
  page_lines <- page_lines[page_lines != ""]
  
  # 定位目标表格的行范围
  start_idx <- min(grep(first_row, page_lines))
  end_idx <- max(grep(last_row, page_lines))
  table_lines <- page_lines[start_idx:end_idx]
  
  # 合并多行项目名称:将无数值的行与下一行合并
  merged_lines <- c()
  i <- 1
  while(i <= length(table_lines)) {
    # 判断当前行是否包含数值(匹配数字或带括号的负数格式)
    has_value <- str_detect(table_lines[i], "\\d|\\(\\d")
    if(!has_value && i < length(table_lines)) {
      merged_lines <- c(merged_lines, paste(table_lines[i], table_lines[i+1]))
      i <- i + 2
    } else {
      merged_lines <- c(merged_lines, table_lines[i])
      i <- i + 1
    }
  }
  
  # 按固定列位置截取每一列内容的辅助函数
  extract_column <- function(line, start, end) {
    substr(line, start, end) %>% trimws()
  }
  
  # 提取所有列数据
  table_data <- lapply(merged_lines, function(line) {
    sapply(1:length(column_positions), function(col) {
      pos <- column_positions[[col]]
      extract_column(line, pos[1], pos[2])
    })
  }) %>% do.call(rbind, .) %>% as.data.frame()
  
  # 设置列名,将空字符串转为NA
  colnames(table_data) <- column_names
  table_data[table_data == ""] <- NA
  
  return(table_data)
}

# 定义列的起始-结束位置(根据PDF表格实际布局调整)
column_positions <- list(
  c(1, 45),   # 项目列
  c(46, 60),  # 2022半年列
  c(61, 75),  # 2021半年列
  c(76, 90),  # 2022全年列
  c(91, 100)  # 备注列
)
column_names <- c("Item","6m 30-9-2022","6m 30-9-2021","12m 30-3-2022","Remarks")

# 运行函数获取修正后的数据
fixed_output <- scrape_pdf_fixed(pdf_data, 3, column_positions, column_names, "Care fees", "Basic and diluted")

修正效果

原本错位的行数据会被正确拆分,备注列内容归位,多行项目名称合并为完整内容:

# 关键行示例输出
fixed_output[c(7,14),]
#>                                        Item 6m 30-9-2022 6m 30-9-2021 12m 30-3-2022 Remarks
#>7 Fair-value movement of investment properties            3      261,346       285,143 745,885
#>14                      Impairment loss            2     (10,784)             -       -

关键说明

  • 固定列位置:PDF表格的列是绝对对齐的,用substr截取比空格拆分更稳定,列位置可通过打印原始行、观察字符位置调整;
  • 多行合并:通过判断行是否包含数值,自动合并拆分的项目名称行,避免表头拆分导致的数据错位;
  • 空值标准化:将空字符串转为NA,方便后续数据清洗与分析。

内容的提问来源于stack exchange,提问作者Webko Wuite

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 05:25:13