title: [Extracting PDF Text with R and Creating Tidy Data]
author: 富士山下裸奔
date: 2018.4.10.
前言:
在當(dāng)今的數(shù)字時代芋肠,數(shù)據(jù)有多種形式筋现。許多常見的文件類型廓八,如CSV、XLSX和純文本(TXT)都很容易訪問和管理。然而饭宾,有時候,我們需要的數(shù)據(jù)被鎖定在文件格式中,這種格式不太容易訪問楞抡,比如PDF。如果你發(fā)現(xiàn)自己處于這種困境析藕,不要擔(dān)心——pdftools
包幫你解決難題召廷。
在這篇文章中,您將學(xué)習(xí)如何:使用pdftools
從PDF中提取文本,使用stringr
包來操作字符串的文本,并創(chuàng)建一個整潔的數(shù)據(jù)集。數(shù)據(jù)來源來自加州大學(xué)男子籃球隊(duì)的統(tǒng)計(jì)數(shù)據(jù)。
最后竞慢,我將會創(chuàng)建一個顯示賽季統(tǒng)計(jì)數(shù)據(jù)的tibble先紫,包括每個球員的上場時間、投籃命中率筹煮、總得分和平均每場得分遮精。
step 1
是加載所需的R包。stringr 包是R包的tidyverse集合中的一個成員中的一個败潦,其中的軟件包旨在使數(shù)據(jù)科學(xué)變得容易本冲。我強(qiáng)烈推薦Hadley Wickham和Garrett Grolemund編寫的R for Data Science。對于初學(xué)者來說劫扒,這是一本很棒的書檬洞,對于更高級的程序員來說,這也是一個口袋參考沟饥。
library(pdftools)
library(tidyverse)
step 2
下一步將使用pdf_text命令來讀取文件的文本添怔,創(chuàng)建新對象UC_text
, read_lines()
函數(shù)讀取文件的行。
UC_text <- pdf_text("./data/UC_stats.pdf") %>%
readr::read_lines()
head(UC_text)
把重點(diǎn)放在球員的賽季統(tǒng)計(jì)上闷板,這是我們文件的第6行到第24行澎灸。第6行包含我們生成的數(shù)據(jù)的列名,將數(shù)據(jù)框命名為season_stats
遮晚。
season_stats <- UC_text[6:24]
head(season_stats)
step 3
在接下來的一系列步驟中性昭,將使用 stringr
·包中的函數(shù)來將文本行轉(zhuǎn)換成一個理想的形式。處理的第一個問題是每一行文本中不同元素之間的空白县遣。str_squish()
函數(shù)的作用是:減少每個字符串之間的重復(fù)空格糜颠。還需要刪除每個玩家的名字和名字之間的逗號。將使用str_replace_all()
來刪除逗號萧求。
str_squish()
同str_trim()
.用法如下:
str_trim()
removes whitespace from start and end of string
str_squish()
also reduces repeated whitespace inside a string
str_trim(" String\t") #String
str_squish("\n\nString with\n\n") #String with
在刪除了空格和逗號之后其兴,我可以把重點(diǎn)放在分離每個元素上。我將使用strsplt()
將每個字符串的元素拆分為子字符串夸政。
all_stats_lines <- season_stats[1:16] %>%
str_squish() %>%
str_replace_all(",", "") %>%
strsplit(split = " ")
head(all_stats_lines)
all_stats_lines
對象的結(jié)構(gòu)是一個列表≡現(xiàn)在關(guān)注第一個元素,它將是數(shù)據(jù)框的列名守问。這里有兩個問題:1.有三個元素被命名為“avg”2.)只有一個元素被命名為Player匀归,但是每個玩家的名字都被分成兩列(我稍后會修正)。現(xiàn)在耗帕,我將重點(diǎn)討論更改列名穆端。我將使用unlist()
將第一個元素和轉(zhuǎn)換列表設(shè)置為一個字符向量。一旦我將它們轉(zhuǎn)換回字符向量仿便,可以很容易地將新值賦給我們的列名体啰。
var_lines <- all_stats_lines[1] %>%
unlist()
var_lines
var_lines的第5個攒巍、第15個和第23個元素都被命名為avg。根據(jù)矢量(和一些籃球技術(shù))的前面元素荒勇,我們可以推斷出這些元素分別代表平均上場時間柒莉、平均籃板數(shù)和平均得分。我將重命名這些元素枕屉,' avg_min '常柄, ' avg_min ', ' avg_pts '
var_lines[c(5, 15, 23)] <- c("avg_min", "avg_reb", "avg_pts")
str(var_lines)
var_lines
step 4
下一個主要障礙是將球員統(tǒng)計(jì)數(shù)據(jù)轉(zhuǎn)換成一個數(shù)據(jù)框搀擂。我將在plyr
包中使用ldply()
函數(shù),該函數(shù)將一個函數(shù)應(yīng)用于列表中的每個元素卷玉,并將結(jié)果合并到一個數(shù)據(jù)框中哨颂。
stats_lines <- all_stats_lines[2:16]
head(stats_lines)
現(xiàn)在是時候回到玩家名字的問題上來了。請記住相种,列名稱的數(shù)量與籃球統(tǒng)計(jì)數(shù)據(jù)的列不一致威恼,因?yàn)樵?strong>stats_df對象中每個參與者的名稱都是由兩個列(“V1”和“V2”)分隔的。
為了將這些列與每個參與者的名字和名字組合起來寝并,將使用unite()函數(shù)
Unite multiple columns into one.
`Description`
Convenience function to paste together multiple columns into one.
Usage
unite(data, col, ..., sep = "_", remove = TRUE)
stats_df <- plyr::ldply(stats_lines) %>%
unite(v2v2, V2, V3, sep = ",")
head(stats_df)
colnames(stats_df) <- var_lines
head(stats_df)
現(xiàn)在我們的列終于對齊了箫措,我終于可以組裝最終的數(shù)據(jù)框架了。第一步是使用colnames()
附加列名衬潦。我想把我最后的數(shù)據(jù)幀轉(zhuǎn)換成一個小塊斤蔓。有很多理由可以讓你的生活成為一個數(shù)據(jù)科學(xué)家的生活。其中之一就是tibbles容易處理non-syntactic 變量镀岛。為了引用non-syntactic變量弦牡,它們必須在backticks中被包圍。
Find_DF <- as.tibble(stats_df) %>%
select("##", Player, min,"fg%", pts, avg_pts)
head(Find_DF)
現(xiàn)在有了一個干凈整潔的最終數(shù)據(jù)集漂羊,可以進(jìn)行分析驾锰、可視化或?qū)С觥?br>
參考文獻(xiàn):
https://www.r-bloggers.com/extracting-pdf-text-with-r-and-creating-tidy-data/