官术网_书友最值得收藏!

2.3 數據導入

數據分析師可能經常會遇到來自不同數據源和數據格式的數據。例如,csv/txt的文本文件數據、存儲在數據庫中的銷售數據,或者需要從網絡上爬取數據來豐富你的數據源、從Hive中直接讀取數據等。下面我們來學習如何將不同數據源的數據導入R工具中。

2.3.1 利用RStudio導入

R暫時沒有很好用的可視化數據導入工具,所以需要使用命令來導入/導出數據。但可以使用Rstudio編輯器的簡單數據導入功能,如圖2-11所示。

圖2-11 利用RStudio導入csv/txt及網絡數據

假如在C:\Users\Think\Documents文件夾下有一個文件:iris.csv。在RStudio右上角窗口的Import Dataset下拉列表中選擇From Local Files,選中iris.csv文件后單擊打開,得到如圖2-12所示的窗口。

圖2-12 利用RStudio導入csv/txt及網絡數據

窗口左側的Name表示導入數據時要保存的數據對象名稱,RStuido會默認獲取與導入文件名稱相同的對象名稱,當然,也可以手動修改成自己需要的名稱。其他選項包括編碼類型、是否需要標題、分隔符、缺失值的處理、字符串是否轉換成因子等參數設置。窗口右上角是導入的數據源預覽,右下角是數據導入R中的預覽。參數調整完成后,單擊Import按鈕將數據導入R中。

Justin Rao的網站上有份從2002年到2008年間的NBA工資數據:http://www.justinmrao.com/salary_data.csv。可以在RStudio右上角窗口的Import Dataset下拉列表中選擇From Web URL,在打開的窗口中輸入以上的網址后單擊OK按鈕,即可完成網絡數據的下載,如圖2-13所示。

圖2-13 輸入網絡地址

數據下載完成會出現與從本地導入csv文件相同的窗口,單擊Import按鈕,即可把數據導入R工具中,如圖2-14所示。

圖2-14 數據設置窗口

2.3.2 文本文件的導入

有眾多的格式和文本文件標準可用于存儲數據。用于存儲數據的通用格式為分隔符值(即CSV或制表符分隔文件)、可擴展標記語言(XML)、JavaScript對象表示法(JSON),其中,最常用于存儲數據的通用格式為分隔符值(即CSV或制表符分隔文件)。

假如當前目錄下有兩個文件:iris.txt和iris.csv。可以利用read.table函數將這兩份數據讀入R工具中。

> import.txt <- read.table("iris.txt",header = TRUE) # 讀入iris.txt文件
> head(import.txt)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
4          4.6         3.1          1.5         0.2  setosa
5          5.0         3.6          1.4         0.2  setosa
6          5.4         3.9          1.7         0.4  setosa

read.table函數的第一個參數file是導入目錄中的數據,如果數據不在當前目錄中,則需要增加完整路徑;參數header用來設置導入的數據是否有變量名稱,默認是FALSE;參數sep默認以一個或多個空格、制表符、換行或回車為字段分隔符,因為csv文件以逗號作為字段分隔符,故如果導入csv文件,需要將參數sep設置為”,”。

> import.csv <- read.table("iris.csv", sep = ",") #讀入iris.csv文件
> head(import.csv)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
4          4.6         3.1          1.5         0.2  setosa
5          5.0         3.6          1.4         0.2  setosa
6          5.4         3.9          1.7         0.4  setosa

有幾個read.table的包裝函數使用起來比較方便。read.csv函數默認將分隔符設置為逗號,并假設數據有標題行。

> import.csv1 <- read.csv("iris.csv") # 利用read.csv將iris.csv文件讀入
> head(import.csv1)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
4          4.6         3.1          1.5         0.2  setosa
5          5.0         3.6          1.4         0.2  setosa
6          5.4         3.9          1.7         0.4  setosa

不是所有的文本文件都像定界符文件那樣有一個定義良好的結構。如果文件的結構松散,更簡單的做法是:先讀入文件中的所有文本行,再對其內容進行文本分詞及挖掘。readLines(注意兩個單詞間沒有點連接,且第二個單詞的首字母是大寫字母L)就提供了這種方法。它接受一個文件路徑(或文件連接)和一個可選的最大行數作為參數來讀取文件。

> unstructuredText <- readLines("unstructuredText.txt")
> unstructuredText
[1] "R語言是一套開源的數據分析解決方案,幾乎可以獨立完成數據處理、數據可視化、數據建模及模型評估等工作,而且可以完美配合其他工具進行數據交互。具體來說,R語言具有以下優勢:"
[2] "1)高效的數據處理能力"
[3] "2)數據分析"
[4] "3)數據可視化"
[5] "4)通過龐大的R程序包庫文件進行擴展"

2.3.3 Excel文件的導入

讀取一個Excel文件的最好方式,就是在Excel中將其導出為一個逗號分隔值文件(csv),并使用read.csv()的方式將其導入R中。R中也有好幾個包可以直接將Excel文件導入R中,如RODBC包中的odbcConnectExcel2007函數、xlsx包中的read.xlsx函數、XLConnect包中的loadworkbook和readWorksheet函數、readxl包中的read_excel函數。

假如有一個sample.xlsx文件,利用4種方式將其讀入R中。

> # 利用RODBC包讀入
> library(RODBC)
> channel <- odbcConnectExcel2007("sample.xlsx") # 建立連接
> odbcdf <- sqlFetch(channel,'data')      # 讀取工作表data的數據
> odbcClose(channel)                 # 關閉連接
> odbcdf總序號性別年齡職業
1      1    1    5    4
2      2    2    2    1
3      3    2    1    1
4      4    1    2    1
5      5    1    3    5
> # 利用xlsx包讀取EXcel數據
> library(xlsx)載入需要的程輯包:rJava載入需要的程輯包:xlsxjars
> res <- read.xlsx('sample.xlsx',1 , encoding="UTF-8")    # 利用read.xlsx函數讀取Excel文件
> res總序號性別年齡職業
1      1    1    5    4
2      2    2    2    1
3      3    2    1    1
4      4    1    2    1
5      5    1    3    5
> detach(package:xlsx)
> # 利用XLConnect包讀取Excel數據
> library(XLConnect)
> wb <- loadWorkbook("sample.xlsx")       # 將工作簿加載到R中
> xldf<-readWorksheet(wb,sheet=getSheets(wb)[1])  # 讀取第一個工作表的數據
> xldf總序號性別年齡職業
1      1    1    5    4
2      2    2    2    1
3      3    2    1    1
4      4    1    2    1
5      5    1    3    5
> # 利用readxl包讀取Excel數據
> library(readxl)
> readexcel <- read_excel("sample.xlsx",1,col_names = T)
> readexcel
# A tibble: 5 × 4總序號性別年齡職業
<dbl><dbl><dbl><dbl>
1      1     1     5     4
2      2     2     2     1
3      3     2     1     1
4      4     1     2     1
5      5     1     3     5

2.3.4 數據庫文件的導入

在R中通過RODBC包訪問一個數據庫也許是最流行的方式。這種方式允許R連接到任意一種擁有ODBC驅動的數據庫,其實幾乎就是市面上的所有數據庫。

現在,嘗試用RODBC連接生產環境中的MySQL數據庫。由于服務器上的MySQL是32位,計算機系統是64位,所以需要在C:\Windows\SysWOW64文件夾下找到odbcad32.exe,雙擊打開ODBC數據源管理器界面,如圖2-15所示。

圖2-15 ODBC數據源管理器界面

單擊“添加”按鈕,選擇MySQL ODBC驅動,完成之后會彈出一個數據庫配置的對話框,如圖2-16所示。

圖2-16 填寫ODBC信息

填寫完數據庫信息,單擊Test按鈕測試連接成功,在64位的Windows下配置好32位的MySQL ODBC,如圖2-17所示。

圖2-17 ODBC測試成功

在32位的R中利用install.packages("RODBC")命令安裝RODBC包。包下載安裝好后,可以利用包中的odbcConnect(dsn,uid="",pwd="",...)函數連接數據庫,并繼續數據的傳輸及分析工作。

> library(RODBC)
> channel <- odbcConnect("daniel","root","123456")        # 建立連接
> odbcGetInfo(channel)                                       # 顯示數據庫信息
DBMS_Name          DBMS_Ver        Driver_ODBC_Ver
"MySQL"             "5.5.28"                "03.80"
Data_Source_Name        Driver_Name             Driver_Ver
"daniel"        "myodbc5a.dll"           "05.03.0006"
ODBC_Ver        Server_Name
"03.80.0000" "localhost via TCP/IP"

可以使用sqlSave(channel,dat,tablename=NULL,append=FALSE)命令將R中的數據框寫入或更新(append=TRUE)到MySQL數據庫的某個表中。比如想把R自帶的mtcars數據寫入MySQL中,在數據庫中生成新表mydata。

# 將mtcars數據集寫入MySQL中
> sqlSave(channel,mtcars,"mydata",append = FALSE)

在MySQL中查詢剛生成的新表mydata,結果如圖2-18所示。

圖2-18 將R中的數據框寫入MySQL中

可以利用sqlFetch(channel,sqtable,...,colnames=FALSE,rownames=TRUE)命令將MySQL數據庫中的mydata表讀取到一個數據框中。

> mydata <- sqlFetch(channel,"mydata")
> str(mydata)
'data.frame':   32 obs. of  11 variables:
$ mpg : num  21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
$ cyl : num  6 6 4 6 8 6 8 4 4 6 ...
$ disp: num  160 160 108 258 360 ...
$ hp  : num  110 110 93 110 175 105 245 62 95 123 ...
$ drat: num  3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
$ wt  : num  2.62 2.88 2.32 3.21 3.44 ...
$ qsec: num  16.5 17 18.6 19.4 17 ...
$ vs  : num  0 0 1 1 0 1 0 1 1 1 ...
$ am  : num  1 1 1 0 0 0 0 0 0 0 ...
$ gear: num  4 4 4 3 3 3 3 4 4 4 ...
$ carb: num  4 4 1 1 2 1 4 2 2 4 ...

可以使用sqlQuery(channel,query,errors=TRUE,...,rows_at_time)命令向MySQL數據庫提交一個查詢并返回結果。比如想對mydata表按照vs和am統計分組,并統計mpg的平均組,執行以下代碼可以完成該操作。

> rm(list=ls())
> ls()
character(0)
> result <- sqlQuery(channel,"select vs,am,avg(mpg) from mydata group by vs,am")
> result
vs am avg(mpg)
1  0  0 15.05000
2  0  1 19.75000
3  1  0 20.74286
4  1  1 28.37143

利用sqlDrop(channel,sqtable,errors=TRUE)命令可以直接刪除數據庫中的某個表。比如刪除mydata表,在R中執行以下命令后得到的結果如圖2-19所示。

> sqlDrop(channel,"mydata") # 刪除數據庫中的mydata表
> odbcClose(channel)        # 關閉連接

圖2-19 MySQL中已不存在mydata表

2.3.5 網絡數據的爬取

在網絡數據爬取的過程中,用戶從互聯網上提取嵌入在網頁中的信息,并將其保存為R中的數據結構進一步分析。因為R有內置的Web服務器,所以某些讀取數據的函數默認帶有網絡訪問功能。例如,read.table(或read.csv)可以接受一個URL作為參數。

以Justin Rao的網站上從2002年到2008年間的NBA工資數據為例(http://www.justin-mrao.com/salary_data.csv)進行演示。

> salary_data <- read.csv("http://www.justinmrao.com/salary_data.csv")
> head(salary_data)
team    year     player contract_years_remaining
1      Boston Celtics2002-03Bremer, J.R.                       1
2 Cleveland Cavaliers 2003-04 Bremer, J.R.                       1
3   Charlotte Hornets 2001-02  Brown, P.J.                       7
4 New Orleans Hornets2002-03  Brown, P.J.                       7
5 New Orleans Hornets 2003-04  Brown, P.J.                        4
6 New Orleans Hornets 2004-05  Brown, P.J.                        4
contract_thru position full_name salary_year salary_total year_counter obs
1       2002-03        G    Bremer      349458       349458            1   2
2       2003-04        G    Bremer      563679       563679            2   2
3       2002-03        F     Brown     6404800     36000000            1   6
4       2002-03        F     Brown     7044800     36000000            2   6
5       2006-07        F     Brown     8000000     34000000            3   6
6       2006-07        F     Brown     8000000     34000000            4   6
mean_salary mean_remaining
1    456568.5              1
2    456568.5              1
3   7668267.0              5
4   7668267.0              5
5   7668267.0              5
6   7668267.0              5

完成這個任務的另一種途徑是使用函數readLines下載網頁,然后使用正則表達式對有用的數據進行提取及分析。例如,想爬取一個在線教育網站的所有在線課程(共8頁)的課程名稱、課時數、學生人數、授課老師、課程價格等信息。網頁及源代碼如圖2-20所示。

圖2-20 網站頁面及網頁源代碼

解析網頁源代碼,利用正則表達式提取相關數據。

> # 方法一利用readLines函數和正則表達式提取網頁數據
> # 爬取全部網頁
> web <- NULL
> for(i in 1:8){
+    url <- paste0("https://edu.hellobi.com/course/explore?page=",i)
+    web1 <- readLines(url,encoding = 'UTF-8')
+    web <- c(web1,web)
+ }
> # 提取課程名稱所在的行
> class <- web[grep("class=\"caption\"",web)+3]
> # 刪除多余的空格
> class <- gsub(" ","",class)
> # 提取課時所在的行
> length <- web[grep("class=\"length\"",web)]
> # 利用正則表達式提取課時數
> length <- substr(length,regexpr("i>",length)+2,regexpr("課",length)-1)
> # 提取學生人數
> people <- web[grep("class=\"pull-right people\"",web)]
> people <- substr(people,regexpr(">",people)+1,regexpr("人",people)-1)
> # 提取授課老師
> teacher <- web[grep("class=\"teacher\"",web)]
> for(i in 1:length(teacher)){
+    teacher[i] <-
+substr(teacher[i],gregexpr(">",teacher[i])[[1]][2]+1,gregexpr("<",teacher[i])[[1]][3]-1)
+ }
> # 提取課程價格
> price <- web[grep("class=\"teacher\"",web)+1]
> price <- substr(price,regexpr(">",price)+1,regexpr("/",price)-2)
> # 將結果整理成data.frame形式
> result <- data.frame(課程=class,課時數=length,學生人數=people,
+                      授課老師=teacher,課程價格=price)
> head(result)
課程                                 課時數     學生人數    授課老師   課程價格
1    SSRS2012WIN8Metro高端報表教程            13      1015    IWORK          免費
2    OBIEE深入淺出精品視頻教程            61      150     冰咖啡            1500元
3    問答社區微軟BI問題及性能優化工具合集        10      465     梁勇             免費
4    SSRS2012MetroUI高端報表視頻教程            57      159     BIWORK 1800元
5    天善問答OracleBIEE常見問題視頻教程     3       654     冰咖啡            免費
6    天善內部精品Cognos教程                     8       1041    曾力             免費

也可以用rvest包快速實現以上的數據爬取工作。代碼如下。

> #### 利用rvest包爬取網頁數據
> library(rvest)
> library(magrittr)
> result <- data.frame(課程=1,課時數=1,學生人數=1,授課老師=1,課程價格=1)
> result <- result[-1,]
> for(i in 1:7){
+    url <- paste0("https://edu.hellobi.com/course/explore?page=",i)
+    web <- read_html(url,encoding = 'UTF-8')
+    class <- web %>% html_nodes("div.course-box") %>%
+      html_nodes("img")  # 提取課程名稱
+    class <- substr(class,regexpr("alt=",class)+5,regexpr(">",class)-3)
+    length <- web %>% html_nodes("div.meta") %>% html_nodes("span.length") %>%
+      html_text() # 提取課時數
+    people <- web %>% html_nodes("div.meta")  %>% html_nodes("span.people") %>%
+      html_text()  # 提取學習人數
+    teacher <- web %>% html_nodes("div.meta") %>% html_nodes("span.teacher") %>%
+      html_text()  # 提取老師
+    price <- web %>% html_nodes("div.meta") %>% html_nodes("span.price")  %>%
+      html_text()  # 提取價格
+    result1 <- data.frame(課程=class,課時數=length,學生人數=people,
+                                授課老師=teacher,課程價格=price)
+    result <- data.frame(rbind(result,result1))
+ }
> head(result)
課程                                       課時數  學生人數     授課老師    課程價格
1  機器學習技術在Python語言的商業應用錄播        4課時   94人學習 丘祐瑋     免費
2  Python機器學習kaggle案例                    6課時   166人學習        唐宇迪     免費
3  對話大數據系列技術從破冰到精進               41課時10人學習   MarsJ   499元
4  需求鏈驅動數據化的零售生意錄播               2課時   57人學習 dxcking 免費
5  基本統計方法及其在R中的實現                        5課時   129人學習        黃小明     免費
6  用數據說話-Excel BI商業智能分析零基礎精講課程5課時      9人學習  李奇      499元

R中也有若干用于爬取網絡數據的包,如quantmod、XML、RCurl等,可以爬取各種復雜的網絡數據。其中quantmod包是R平臺用于金融建模的擴展包。主要功能有:從多個數據源獲取歷史數據、繪制金融數據圖表、在金融數據圖表中添加技術指標、計算不同時間尺度的收益率、金融時間序列分析、金融模型擬合與計算,等等。

例如,從雅虎爬取創夢天地(股票代碼:DSKY)上市至今的股價數據。利用get-Symbols函數實現。

> library(quantmod)
> getSymbols("DSKY",scr="yahoo")
> # 查看最后六天的股票記錄
> tail(DSKY)
DSKY.Open DSKY.High DSKY.Low DSKY.Close DSKY.Volume DSKY.Adjusted
2016-05-17     13.53     13.71    13.48      13.55       94000         13.55
2016-05-18     13.44     13.66    13.44      13.66       86400         13.66
2016-05-19     13.61     13.67    13.55      13.58       59400         13.58
2016-05-20     13.58     13.70    13.58      13.69       62400         13.69
2016-05-23     13.67     13.75    13.63      13.70       71200         13.70
2016-05-24     13.67     13.74    13.63      13.67       29900         13.67

getSymbols函數把股票每天的開盤價格、最高價格、最低價格、收盤價格、成交量和調整價格都爬取到R中。可以利用candleChart函數繪制蠟燭圖,如圖2-21所示。

candleChart(DSKY,theme="white") #蠟燭圖

圖2-21 繪制蠟燭圖

主站蜘蛛池模板: 筠连县| 望江县| 隆昌县| 南汇区| 关岭| 陆丰市| 北宁市| 九寨沟县| 大化| 加查县| 亳州市| 元氏县| 察隅县| 梓潼县| 新河县| 泰和县| 西畴县| 东港市| 武夷山市| 绥棱县| 稷山县| 蒙山县| 夏津县| 石屏县| 永德县| 铁力市| 调兵山市| 大新县| 惠来县| 玛曲县| 靖远县| 全南县| 丹棱县| 临西县| 新河县| 淮南市| 义乌市| 绥江县| 谢通门县| 邮箱| 兖州市|