Carlos Carlos - 3 months ago 23
R Question

Transform elements of a list into a table

After reading a pdf in R with the pdftools package I get a list in which every element of the list has a table-like structure, and I would like to aggregate each element of the list maintaining its table structure into a data frame.

Here you have a link to the generated txt file:
https://drive.google.com/open?id=0Bydt25g6hdY-b0NwaDF1NWE0NkU

I have tried this:

table <- list(0)
for (i in test5) { table <- append(table, i)}


But I get the same list.

I would like to be able to have it as a table in which each column is a variable and each row is an observation, removing the date row if possible so that it does not interfere with columns.

Here is the output of
dput(table[1:3])


list(" ",
c("\r\n Thu 04/21/2016 ", "\r\n _No Call Type Attached 0 00:00 00:00 00:00 00:00 00:00 0 0% 0% 00:00 00:00\r\n IEX Billing English 12.5% 1 03:17 00:55 00:03 04:15 00:00 2 200% 0% 00:27 00:00 1 100%\r\n IEX VOB English 50.0% 4 03:15 01:29 01:12 05:57 00:00 1 25% 0% 05:56 00:00 4 100%\r\n IEX VOB Spanish 37.5% 3 03:59 00:20 00:28 04:48 00:00 3 100% 0% 00:20 00:00 3 100%\r\n "
), "\r\n")

Answer

Consider scanning document using readLines() and then split lines by white space to migrate into a character list. Several Filter() calls are used to remove the one-character and empty elements.

file <- "C:\\Path\\To\\Text.txt"

# CONNECT TO FILE, READ LINES
con <- file(description=file, open="r")
pdftext <- readLines(con, warn=FALSE)
close(con)

# FILTER OUT ONE-CHARACTER ELEMENTS
pdftext <- Filter(function(x) nchar(x)>1, pdftext)

# SPLIT LINES BY WHITESPACE / FILTER ONE-CHARACTER ELEMENTS
datalines <- lapply(pdftext, function(x) {
                 tmp <- strsplit(x, "\\s+")[[1]]
                 Filter(function(l) nchar(l)>1, tmp)
})

# FILTER EMPTY ELEMENTS
datalines <- Filter(length, datalines)

# FILL IN NAs TO FIT TABLE COLS (USING 16, LARGEST LENGTH)
datalines <- lapply(datalines, function(x) {
  if(length(x) < 16) {  x <- c(x, rep(NA, 16 - length(x)))
  } else {
    x
  }
})

# BIND ALL LINES INTO CHARACTER MATRIX
datamatrix <- do.call(rbind, datalines)

Output

#       [,1]  [,2]         [,3]      [,4]       [,5]     [,6]     [,7]       [,8]       [,9]       [,10]      [,11]    [,12]  
#  [1,] "Thu" "04/21/2016" "Direct"  "Internal" "Calls:" "Direct" "External" "Calls:"   "Outbound" "Calls:"   NA       NA     
#  [2,] "_No" "Call"       "Type"    "Attached" "00:00"  "00:00"  "00:00"    "00:00"    "00:00"    "0%"       "0%"     "00:00"
#  [3,] "IEX" "Billing"    "English" "12.5%"    "03:17"  "00:55"  "00:03"    "04:15"    "00:00"    "200%"     "0%"     "00:27"
#  [4,] "IEX" "VOB"        "English" "50.0%"    "03:15"  "01:29"  "01:12"    "05:57"    "00:00"    "25%"      "0%"     "05:56"
#  [5,] "IEX" "VOB"        "Spanish" "37.5%"    "03:59"  "00:20"  "00:28"    "04:48"    "00:00"    "100%"     "0%"     "00:20"
...

Character Matrix Output

Comments