Очистка таблиц PDF с пустыми ячейками

#r #pdf #pdftools

#r #PDF #pdftools

Вопрос:

Я использую R для извлечения данных из PDF-файлов, и пока все идет хорошо. Я только что открыл новую партию PDF-файлов и увидел, что мне нужно выяснить, как учитывать пустые ячейки. Я не нашел способа сделать это, и у меня есть сотни страниц, которые мне нужно просмотреть.

Я включил некоторые примеры данных. Я не нашел способа прикрепить сюда PDF-файлы, и они нигде не публикуются в Интернете. Я сохранил df как CSV, затем скопировал и вставил это в документ Word, который я сохранил как CSV для этого примера. Скриншот также прилагается.

 library(pdftools)
library(tidyverse)

# Example data
df <- data.frame("rows" = c("row1", "row2", "row3", "row4", "row5", "row6", "row7", "row8", "row9", "row10"),
                 "col1" = c(1, 2, "", 4, 5, 6, 7, 8, 9, 10),
                 "col2" = c(1, 2, 3, 4, "", "", 7, 8, 9, ""),
                 "col3" = c(1, 2, "", 4, 5, 6, 7, 8, 9, 10),
                 "col4" = c(1, 2, 3, 4, 5, 6, 7, "", 9, 10),
                 "col5" = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
                 "col6" = c(1, 2, "", "", 5, 6, 7, "", 9, 10),
                 "col7" = c(1, 2, 3, 4, 5, "", 7, 8, 9, 10),
                 "col8" = c(1, "", 3, 4, 5, 6, 7, "", 9, 10),
                 "col9" = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
                 )

# Save example data, then save as a PDF outside of R.
# write_csv(df, "sample_data.csv")


# read in the PDF
pdf_file <- pdf_text("sample_data.pdf")

data <- pdf_file[1]
data <- trimws(data)
data <- strsplit(data, "rn")
data <- data[[1]]
data <- str_split_fixed(data, " {2,}", 10)  ## I think this is the step that needs to change
data <- data.frame(data, stringsAsFactors = FALSE)



# Print out outs of the data for reference. 
> data
      X1   X2   X3   X4   X5   X6   X7   X8   X9  X10
1   rows col1 col2 col3 col4 col5 col6 col7 col8 col9
2   row1    1    1    1    1    1    1    1    1    1
3   row2    2    2    2    2    2    2    2    2     
4   row3    3    3    3    3    3    3               
5   row4    4    4    4    4    4    4    4    4     
6   row5    5    5    5    5    5    5    5    5     
7   row6    6    6    6    6    6    6    6          
8   row7    7    7    7    7    7    7    7    7    7
9   row8    8    8    8    8    8    8               
10  row9    9    9    9    9    9    9    9    9    9
11 row10   10   10   10   10   10   10   10   10   


 df
    rows col1 col2 col3 col4 col5 col6 col7 col8 col9
1   row1    1    1    1    1    1    1    1    1    1
2   row2    2    2    2    2    2    2    2         2
3   row3         3         3    3         3    3    3
4   row4    4    4    4    4    4         4    4    4
5   row5    5         5    5    5    5    5    5    5
6   row6    6         6    6    6    6         6    6
7   row7    7    7    7    7    7    7    7    7    7
8   row8    8    8    8         8         8         8
9   row9    9    9    9    9    9    9    9    9    9
10 row10   10        10   10   10   10   10   10   10


 

ОБНОВЛЕНИЕ: добавление dput(pdf_file)

 > dput(pdf_file)
"rows  col1    col2   col3    col4    col5    col6    col7    col8    col9rnrow1        1      1       1       1       1       1       1       1       1rnrow2        2      2       2       2       2       2       2               2rnrow3               3               3       3               3       3       3rnrow4        4      4       4       4       4               4       4       4rnrow5        5              5       5       5       5       5       5       5rnrow6        6              6       6       6       6               6       6rnrow7        7      7       7       7       7       7       7       7       7rnrow8        8      8       8               8               8               8rnrow9        9      9       9       9       9       9       9       9       9rnrow10      10             10      10      10      10      10      10      10rn"
 

Вы можете видеть, что df на этом этапе есть разница между data и. Я попытался поиграть с несколькими вещами, и мне не удалось заставить что-либо работать достаточно хорошо, чтобы опубликовать здесь. Я попытался использовать некоторую логику if / else, чтобы сказать, что если есть 3 или более пробелов, вставьте NA, но это просто вызвало кучу ошибок, поэтому я отказался от этого подхода. Моя цель — получить данные как можно ближе к df.

изображение sample_data в формате pdf

Ответ №1:

Попробуйте использовать read.fwf как файл фиксированной ширины.

 data <- pdf_file[1]
data <- trimws(data)
data <- strsplit(data, "rn")
data <- data[[1]]
writeLines(data, 'temp.txt')
result <- read.fwf('temp.txt', c(11, 2, rep(8, 8)), skip = 1, strip.white = TRUE)
names(result) <- scan(text = readLines('temp.txt', n = 1), what = character())
result

#    rows col1 col2 col3 col4 col5 col6 col7 col8 col9
#1   row1    1    1    1    1    1    1    1    1    1
#2   row2    2    2    2    2    2    2    2   NA    2
#3   row3   NA    3   NA    3    3   NA    3    3    3
#4   row4    4    4    4    4    4   NA    4    4    4
#5   row5    5   NA    5    5    5    5    5    5    5
#6   row6    6   NA    6    6    6    6   NA    6    6
#7   row7    7    7    7    7    7    7    7    7    7
#8   row8    8    8    8   NA    8   NA    8   NA    8
#9   row9    9    9    9    9    9    9    9    9    9
#10 row10   10   NA   10   10   10   10   10   10   10
 

Комментарии:

1. Спасибо. Это дает заголовки моих данных, но не помогает сохранить положение этих пустых ячеек в dataframe, что мне действительно нужно.

2. Yeah..It довольно сложно скорректировать ответ, когда у меня нет необходимых данных. Можете ли вы включить выходные dput(pdf_file) данные в свой пост @pkpto39?

3. Да, я добавил это выше.

4. @pkpto39 Можете ли вы попробовать обновленный ответ, используя read.fwf , он сработал для меня.

5. Спасибо. Потребовалось немного поиграть с шириной, но в конце концов я заставил это работать. Есть ли у вас какие-либо предложения по наилучшему определению ширины столбцов?

Ответ №2:

Это выглядит как хороший сценарий для использования tabulizer пакета. Это работает очень хорошо, когда в PDF есть красиво отформатированные таблицы, подобные этой. Смотрите виньетку. Лучшей функцией здесь для вас было бы tabulizer::extract_tables . Он также должен распознавать пробелы как пустые значения, предполагая, что все PDF-файлы хорошо отформатированы таким образом.

Комментарии:

1. К сожалению, не все данные отформатированы так хорошо, как это, и у меня были всевозможные проблемы с tabulizer. Это может быть вариантом для некоторых из них, поэтому я попробую.