{"id":741,"date":"2015-02-13T10:46:59","date_gmt":"2015-02-13T17:46:59","guid":{"rendered":"http:\/\/homepages.uc.edu\/~yaozo\/wordpress\/?p=741"},"modified":"2015-02-13T10:46:59","modified_gmt":"2015-02-13T17:46:59","slug":"pdf-2-text-or-csv-r","status":"publish","type":"post","link":"https:\/\/zhuoyao.net\/index.php\/2015\/02\/13\/pdf-2-text-or-csv-r\/","title":{"rendered":"PDF-2-text-or-CSV.r"},"content":{"rendered":"<pre id=\"file-pdf-2-text-or-csv-r-LC1\" class=\"line \"><span class=\"pl-c\"># Here are a few methods for getting text from PDF files. Do read through \n<\/span># the instructions carefully! NOte that this code is written for Windows 7,\n# slight adjustments may be needed for other OSs\n# Tell R what folder contains your 1000s of PDFs\n<span class=\"pl-vo\">dest<\/span> <span class=\"pl-k\">&lt;-<\/span> <span class=\"pl-s1\"><span class=\"pl-pds\">\"<\/span>G:\/somehere\/with\/many\/PDFs<span class=\"pl-pds\">\"\n<\/span><\/span># make a vector of PDF file names\n<span class=\"pl-vo\">myfiles<\/span> <span class=\"pl-k\">&lt;-<\/span> list.files(<span class=\"pl-v\">path<\/span> <span class=\"pl-k\">=<\/span> <span class=\"pl-vo\">dest<\/span>, <span class=\"pl-v\">pattern<\/span> <span class=\"pl-k\">=<\/span> <span class=\"pl-s1\"><span class=\"pl-pds\">\"<\/span>pdf<span class=\"pl-pds\">\"<\/span><\/span>, <span class=\"pl-v\">full.names<\/span> <span class=\"pl-k\">=<\/span> <span class=\"pl-c1\">TRUE<\/span>)\n\n# now there are a few options...\n############### PDF (image of text format) to TXT ##########\n# This is for is your PDF is an image of text, this is the case\n# if you open the PDF in a PDF viewer and you cannot select\n# words or lines with your cursor.\n\n##### Wait! #####\n# Before proceeding, make sure you have a copy of Tesseract\n# on your computer! Details &amp; download:\n# https:\/\/code.google.com\/p\/tesseract-ocr\/\n# and a copy of ImageMagick: http:\/\/www.imagemagick.org\/\n# and a copy of pdftoppm on your computer! \n# Download: http:\/\/www.foolabs.com\/xpdf\/download.html\n# And then after installing those three, restart to \n# ensure R can find them on your path. \n# And note that this process can be quite slow...\n# PDF filenames can't have spaces in them for these operations\n# so let's get rid of the spaces in the filenames\nsapply(<span class=\"pl-vo\">myfiles<\/span>, <span class=\"pl-v\">FUN<\/span> <span class=\"pl-k\">=<\/span> <span class=\"pl-k\">function<\/span>(<span class=\"pl-vo\">i<\/span>){file.rename(<span class=\"pl-v\">from<\/span> <span class=\"pl-k\">=<\/span> <span class=\"pl-vo\">i<\/span>, <span class=\"pl-v\">to<\/span> <span class=\"pl-k\">=<\/span> paste0(dirname(<span class=\"pl-vo\">i<\/span>), <span class=\"pl-s1\"><span class=\"pl-pds\">\"<\/span>\/<span class=\"pl-pds\">\"<\/span><\/span>, gsub(<span class=\"pl-s1\"><span class=\"pl-pds\">\"<\/span> <span class=\"pl-pds\">\"<\/span><\/span>, <span class=\"pl-s1\"><span class=\"pl-pds\">\"<\/span><span class=\"pl-pds\">\"<\/span><\/span>, basename(<span class=\"pl-vo\">i<\/span>))))})\n# get the PDF file names without spaces\n<span class=\"pl-vo\">myfiles<\/span> <span class=\"pl-k\">&lt;-<\/span> list.files(<span class=\"pl-v\">path<\/span> <span class=\"pl-k\">=<\/span> <span class=\"pl-vo\">dest<\/span>, <span class=\"pl-v\">pattern<\/span> <span class=\"pl-k\">=<\/span> <span class=\"pl-s1\"><span class=\"pl-pds\">\"<\/span>pdf<span class=\"pl-pds\">\"<\/span><\/span>, <span class=\"pl-v\">full.names<\/span> <span class=\"pl-k\">=<\/span> <span class=\"pl-c1\">TRUE<\/span>)\n# Now we can do the OCR to the renamed PDF files. Don't worry\n# if you get messages like 'Config Error: No display \n# font for...' it's nothing to worry about\nlapply(<span class=\"pl-vo\">myfiles<\/span>, <span class=\"pl-k\">function<\/span>(<span class=\"pl-vo\">i<\/span>){\n# convert pdf to ppm (an image format), just pages 1-10 of the PDF\n# but you can change that easily, just remove or edit the \n# -f 1 -l 10 bit in the line below\nshell(shQuote(paste0(<span class=\"pl-s1\"><span class=\"pl-pds\">\"<\/span>pdftoppm <span class=\"pl-pds\">\"<\/span><\/span>, <span class=\"pl-vo\">i<\/span>, <span class=\"pl-s1\"><span class=\"pl-pds\">\"<\/span> -f 1 -l 10 -r 600 ocrbook<span class=\"pl-pds\">\"<\/span><\/span>)))\n# convert ppm to tif ready for tesseract\nshell(shQuote(paste0(<span class=\"pl-s1\"><span class=\"pl-pds\">\"<\/span>convert *.ppm <span class=\"pl-pds\">\"<\/span><\/span>, <span class=\"pl-vo\">i<\/span>, <span class=\"pl-s1\"><span class=\"pl-pds\">\"<\/span>.tif<span class=\"pl-pds\">\"<\/span><\/span>)))\n# convert tif to text file\nshell(shQuote(paste0(<span class=\"pl-s1\"><span class=\"pl-pds\">\"<\/span>tesseract <span class=\"pl-pds\">\"<\/span><\/span>, <span class=\"pl-vo\">i<\/span>, <span class=\"pl-s1\"><span class=\"pl-pds\">\"<\/span>.tif <span class=\"pl-pds\">\"<\/span><\/span>, <span class=\"pl-vo\">i<\/span>, <span class=\"pl-s1\"><span class=\"pl-pds\">\"<\/span> -l eng<span class=\"pl-pds\">\"<\/span><\/span>)))\n# delete tif file\nfile.remove(paste0(<span class=\"pl-vo\">i<\/span>, <span class=\"pl-s1\"><span class=\"pl-pds\">\"<\/span>.tif<span class=\"pl-pds\">\"<\/span><\/span> ))\n})\n# where are the txt files you just made?\n<span class=\"pl-vo\">dest<\/span> <span class=\"pl-c\"># in this folder\n<\/span># And now you're ready to do some text mining on the text files\n############### PDF (text format) to TXT ###################\n\n\n##### Wait! #####\n# Before proceeding, make sure you have a copy of pdf2text\n# on your computer! Details: https:\/\/en.wikipedia.org\/wiki\/Pdftotext\n# Download: http:\/\/www.foolabs.com\/xpdf\/download.html\n# If you have a PDF with text, ie you can open the PDF in a \n# PDF viewer and select text with your curser, then use these \n# lines to convert each PDF file that is named in the vector \n# into text file is created in the same directory as the PDFs\n# note that my pdftotext.exe is in a different location to yours\nlapply(<span class=\"pl-vo\">myfiles<\/span>, <span class=\"pl-k\">function<\/span>(<span class=\"pl-vo\">i<\/span>) system(paste(<span class=\"pl-s1\"><span class=\"pl-pds\">'<\/span>\"C:\/Program Files\/xpdf\/bin64\/pdftotext.exe\"<span class=\"pl-pds\">'<\/span><\/span>, paste0(<span class=\"pl-s1\"><span class=\"pl-pds\">'<\/span>\"<span class=\"pl-pds\">'<\/span><\/span>, <span class=\"pl-vo\">i<\/span>, <span class=\"pl-s1\"><span class=\"pl-pds\">'<\/span>\"<span class=\"pl-pds\">'<\/span><\/span>)), <span class=\"pl-v\">wait<\/span> <span class=\"pl-k\">=<\/span> <span class=\"pl-c1\">FALSE<\/span>) )\n\n# where are the txt files you just made?\n<span class=\"pl-vo\">dest<\/span> <span class=\"pl-c\"># in this folder\n<\/span># And now you're ready to do some text mining on the text files\n\n############### PDF to CSV (DfR format) ####################\n# or if you want DFR-style csv files...\n# read txt files into R\n<span class=\"pl-vo\">mytxtfiles<\/span> <span class=\"pl-k\">&lt;-<\/span> list.files(<span class=\"pl-v\">path<\/span> <span class=\"pl-k\">=<\/span> <span class=\"pl-vo\">dest<\/span>, <span class=\"pl-v\">pattern<\/span> <span class=\"pl-k\">=<\/span> <span class=\"pl-s1\"><span class=\"pl-pds\">\"<\/span>txt<span class=\"pl-pds\">\"<\/span><\/span>, <span class=\"pl-v\">full.names<\/span> <span class=\"pl-k\">=<\/span> <span class=\"pl-c1\">TRUE<\/span>)\nlibrary(<span class=\"pl-vo\">tm<\/span>)\n<span class=\"pl-vo\">mycorpus<\/span> <span class=\"pl-k\">&lt;-<\/span> Corpus(DirSource(<span class=\"pl-vo\">dest<\/span>, <span class=\"pl-v\">pattern<\/span> <span class=\"pl-k\">=<\/span> <span class=\"pl-s1\"><span class=\"pl-pds\">\"<\/span>txt<span class=\"pl-pds\">\"<\/span><\/span>))\n# warnings may appear after you run the previous line, they\n# can be ignored\n<span class=\"pl-vo\">mycorpus<\/span> <span class=\"pl-k\">&lt;-<\/span> tm_map(<span class=\"pl-vo\">mycorpus<\/span>, <span class=\"pl-vo\">removeNumbers<\/span>)\n<span class=\"pl-vo\">mycorpus<\/span> <span class=\"pl-k\">&lt;-<\/span> tm_map(<span class=\"pl-vo\">mycorpus<\/span>, <span class=\"pl-vo\">removePunctuation<\/span>)\n<span class=\"pl-vo\">mycorpus<\/span> <span class=\"pl-k\">&lt;-<\/span> tm_map(<span class=\"pl-vo\">mycorpus<\/span>, <span class=\"pl-vo\">stripWhitespace<\/span>)\n<span class=\"pl-vo\">mydtm<\/span> <span class=\"pl-k\">&lt;-<\/span> DocumentTermMatrix(<span class=\"pl-vo\">mycorpus<\/span>)\n# remove some OCR weirdness\n# words with more than 2 consecutive characters\n<span class=\"pl-vo\">mydtm<\/span> <span class=\"pl-k\">&lt;-<\/span> <span class=\"pl-vo\">mydtm<\/span>[,<span class=\"pl-k\">!<\/span>grepl(<span class=\"pl-s1\"><span class=\"pl-pds\">\"<\/span>(.)<span class=\"pl-cce\">\\\\<\/span>1{2,}<span class=\"pl-pds\">\"<\/span><\/span>, <span class=\"pl-vo\">mydtm<\/span><span class=\"pl-k\">$<\/span><span class=\"pl-vo\">dimnames<\/span><span class=\"pl-k\">$<\/span><span class=\"pl-vo\">Terms<\/span>)]\n\n# get each doc as a csv with words and counts\n<span class=\"pl-k\">for<\/span>(<span class=\"pl-vo\">i<\/span> <span class=\"pl-k\">in<\/span> <span class=\"pl-c1\">1<\/span><span class=\"pl-k\">:<\/span>nrow(<span class=\"pl-vo\">mydtm<\/span>)){\n# get word counts\n<span class=\"pl-vo\">counts<\/span> <span class=\"pl-k\">&lt;-<\/span> as.vector(as.matrix(<span class=\"pl-vo\">mydtm<\/span>[<span class=\"pl-c1\">1<\/span>,]))\n# get words\n<span class=\"pl-vo\">words<\/span> <span class=\"pl-k\">&lt;-<\/span> <span class=\"pl-vo\">mydtm<\/span><span class=\"pl-k\">$<\/span><span class=\"pl-vo\">dimnames<\/span><span class=\"pl-k\">$<\/span><span class=\"pl-vo\">Terms\n<\/span># combine into data frame\n<span class=\"pl-vo\">df<\/span> <span class=\"pl-k\">&lt;-<\/span> <span class=\"pl-st\">data.frame<\/span>(<span class=\"pl-v\">word<\/span> <span class=\"pl-k\">=<\/span> <span class=\"pl-vo\">words<\/span>, <span class=\"pl-v\">count<\/span> <span class=\"pl-k\">=<\/span> <span class=\"pl-vo\">counts<\/span>,<span class=\"pl-v\">stringsAsFactors<\/span> <span class=\"pl-k\">=<\/span> <span class=\"pl-c1\">FALSE<\/span>)\n# exclude words with count of zero\n<span class=\"pl-vo\">df<\/span> <span class=\"pl-k\">&lt;-<\/span> <span class=\"pl-vo\">df<\/span>[<span class=\"pl-vo\">df<\/span><span class=\"pl-k\">$<\/span><span class=\"pl-vo\">count<\/span> <span class=\"pl-k\">!=<\/span> <span class=\"pl-c1\">0<\/span>,]\n# write to CSV with original txt filename\nwrite.csv(<span class=\"pl-vo\">df<\/span>, paste0(<span class=\"pl-vo\">mydtm<\/span><span class=\"pl-k\">$<\/span><span class=\"pl-vo\">dimnames<\/span><span class=\"pl-k\">$<\/span><span class=\"pl-vo\">Docs<\/span>[<span class=\"pl-vo\">i<\/span>],<span class=\"pl-s1\"><span class=\"pl-pds\">\"<\/span>.csv<span class=\"pl-pds\">\"<\/span><\/span>), <span class=\"pl-v\">row.names<\/span> <span class=\"pl-k\">=<\/span> <span class=\"pl-c1\">FALSE<\/span>)\n}\n\n# and now you're ready to work with the csv files\n\n############### PDF to TXT (all text between two words) ####\n\n# Below is about splitting the text files at certain characters\n## can be skipped...\n\n# if you just want the abstracts, we can use regex to extract that part of\n# each txt file, Assumes that the abstract is always between the words 'Abstract'\n# and 'Introduction'\n<span class=\"pl-vo\">abstracts<\/span> <span class=\"pl-k\">&lt;-<\/span> lapply(<span class=\"pl-vo\">mytxtfiles<\/span>, <span class=\"pl-k\">function<\/span>(<span class=\"pl-vo\">i<\/span>) {\n<span class=\"pl-vo\">j<\/span> <span class=\"pl-k\">&lt;-<\/span> paste0(scan(<span class=\"pl-vo\">i<\/span>, <span class=\"pl-v\">what<\/span> <span class=\"pl-k\">=<\/span> <span class=\"pl-st\">character<\/span>()), <span class=\"pl-v\">collapse<\/span> <span class=\"pl-k\">=<\/span> <span class=\"pl-s1\"><span class=\"pl-pds\">\"<\/span> <span class=\"pl-pds\">\"<\/span><\/span>)\nregmatches(<span class=\"pl-vo\">j<\/span>, gregexpr(<span class=\"pl-s1\"><span class=\"pl-pds\">\"<\/span>(?&lt;=Abstract).*?(?=Introduction)<span class=\"pl-pds\">\"<\/span><\/span>, <span class=\"pl-vo\">j<\/span>, <span class=\"pl-v\">perl<\/span><span class=\"pl-k\">=<\/span><span class=\"pl-c1\">TRUE<\/span>))\n})# Write abstracts into separate txt files...\n# write abstracts as txt files \n# (or use them in the list for whatever you want to do next)\nlapply(<span class=\"pl-c1\">1<\/span><span class=\"pl-k\">:<\/span>length(<span class=\"pl-vo\">abstracts<\/span>), <span class=\"pl-k\">function<\/span>(<span class=\"pl-vo\">i<\/span>) write.table(<span class=\"pl-vo\">abstracts<\/span>[<span class=\"pl-vo\">i<\/span>], <span class=\"pl-v\">file<\/span><span class=\"pl-k\">=<\/span>paste(<span class=\"pl-vo\">mytxtfiles<\/span>[<span class=\"pl-vo\">i<\/span>], <span class=\"pl-s1\"><span class=\"pl-pds\">\"<\/span>abstract<span class=\"pl-pds\">\"<\/span><\/span>, <span class=\"pl-s1\"><span class=\"pl-pds\">\"<\/span>txt<span class=\"pl-pds\">\"<\/span><\/span>, <span class=\"pl-v\">sep<\/span><span class=\"pl-k\">=<\/span><span class=\"pl-s1\"><span class=\"pl-pds\">\"<\/span>.<span class=\"pl-pds\">\"<\/span><\/span>), <span class=\"pl-v\">quote<\/span> <span class=\"pl-k\">=<\/span> <span class=\"pl-c1\">FALSE<\/span>, <span class=\"pl-v\">row.names<\/span> <span class=\"pl-k\">=<\/span> <span class=\"pl-c1\">FALSE<\/span>, <span class=\"pl-v\">col.names<\/span> <span class=\"pl-k\">=<\/span> <span class=\"pl-c1\">FALSE<\/span>, <span class=\"pl-v\">eol<\/span> <span class=\"pl-k\">=<\/span> <span class=\"pl-s1\"><span class=\"pl-pds\">\"<\/span> <span class=\"pl-pds\">\"<\/span><\/span> ))\n# And now you're ready to do some text mining on the txt \n# originally on http:\/\/stackoverflow.com\/a\/21449040\/1036500<\/pre>\n","protected":false},"excerpt":{"rendered":"<p># Here are a few methods for getting text from PDF files. Do read through # the instructions carefully! NOte that this code is written&hellip; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[20],"tags":[],"class_list":["post-741","post","type-post","status-publish","format-standard","hentry","category-r"],"_links":{"self":[{"href":"https:\/\/zhuoyao.net\/index.php\/wp-json\/wp\/v2\/posts\/741","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/zhuoyao.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/zhuoyao.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/zhuoyao.net\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/zhuoyao.net\/index.php\/wp-json\/wp\/v2\/comments?post=741"}],"version-history":[{"count":0,"href":"https:\/\/zhuoyao.net\/index.php\/wp-json\/wp\/v2\/posts\/741\/revisions"}],"wp:attachment":[{"href":"https:\/\/zhuoyao.net\/index.php\/wp-json\/wp\/v2\/media?parent=741"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/zhuoyao.net\/index.php\/wp-json\/wp\/v2\/categories?post=741"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/zhuoyao.net\/index.php\/wp-json\/wp\/v2\/tags?post=741"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}