R讀取並處理較大數據

1. 概述

以前在讀取和處理較大的csv數據時,在嘗試了一次直接讀取處理後發現很是耗時,就改用導入數據庫,再經過RMySQL或者RODBC來讀取處理數據。今天來比較一下。mysql

加載相關packagessql

library(data.table)
library(dplyr)
library(sqldf)
library(lubridate)
library(RMySQL)

2. 讀取數據

2.1 使用data.table

首先經過data.table的fread()讀取數據,fread()read.csv()的效率高不少,這裏不進行詳細比較。數據庫

time_fread <- system.time(
test <- fread("test.csv")
)
## 數據的大小
paste("數據的大小爲:",format(object.size(test),units="auto"))

數據的大小爲: 573.1 Mbunix

2.2 使用RMySQL

導入數據庫後效率最高,雖然導入數據庫消耗的時間較長,但便於後續統計.code

con <- dbConnect(MySQL(),host="localhost",dbname="test_db",user="root",password="root")
# dbListTables(con)
# dbRemoveTable(con,"test")
# 將數據寫入數據庫
time_mysql_write <- system.time(
  dbWriteTable(con,"test",test)
)

經過R導入數據庫的效率,相對比較耗時,建議經過其餘方式導入。orm

kable(rbind(time_mysql_write),row.names = F)
user.self sys.self elapsed user.child sys.child
124.757 2.822 151.031 0.779 0.053

讀取數據庫中的數據表it

time_mysql_read <- system.time(
  db_test <- dbReadTable(con,"test")
)
time_mysql_query <- system.time(
  db_test <- dbGetQuery(con,"select * from test")
)

2.3 讀取數據比較

kable(rbind(time_fread,time_mysql_read))
name user.self sys.self elapsed user.child sys.child
time_fread 6.534 0.455 7.265 0 0
time_mysql_read 13.185 1.441 25.888 0 0
time_mysql_query 6.338 1.298 18.143 0 0

很明顯fread()的效率最高,因此若是隻是讀取數據,仍是強烈推薦fread()。針對讀取數據庫表所有數據,dbReadTable()dbGetQuery()讀取數據的效率還差。table

3. 處理數據

分別經過data.table、dplyr、sqldf、RMySQL這四種方式來統計相關數據。ast

3.1 使用data.table

time_DT <- system.time(
test_month1 <- test[,.(value = sum(數據)), by=.(year=year(日期), month = month(日期))]
)

3.2 使用dplyr

time_dplyr <- system.time(
test_month2 <- test %>%
  group_by(year=year(日期),month=month(日期)) %>%
  summarise(value=sum(數據)) %>%
  ungroup()
)

3.3 使用sqldf

## 須要先卸載RMySQL
detach("package:RMySQL", unload=TRUE)
time_sqldf_s <- proc.time()
test$日期 <- as.Date(test[,日期])

test_month3 <- sqldf("select strftime('%Y', 日期 * 3600 * 24, 'unixepoch') as year,
strftime('%m',日期) as month,sum(數據) as test_amount from test group by strftime('%Y', 日期 * 3600 * 24, 'unixepoch'),
strftime('%m',日期)")
time_sqldf <- proc.time()-time_sqldf_s

3.4 使用RMySQL

library(RMySQL)
con <- dbConnect(MySQL(),host="localhost",dbname="test_db",user="root",password="root")
test_month_sql <- "SELECT YEAR(日期) as year, month(日期) as month,
sum(數據) as test_amount FROM test GROUP BY YEAR(日期),month(日期)"
time_mysql <- system.time(
  test_month4 <- dbGetQuery(con, test_month_sql)
)

3.5 處理數據比較

rbind(time_DT,time_dplyr,time_sqldf,time_mysql)
name user.self sys.self elapsed user.child sys.child
time_DT 7.846 1.112 9.063 0 0
time_dplyr 8.155 1.182 9.487 0 0
time_sqldf 37.343 2.650 40.868 0 0
time_mysql 0.001 0.000 2.449 0 0

經過數據庫來處理數據效率最高,其次爲data.tabledplyr,兩者不相伯仲,data.table語法更加優雅易讀,dplyr語法更加簡潔,看本身的喜愛啦。而sqldf的效率最差,不推薦。form

4. 總結

推薦使用data.table的fread()讀取數據,再導入數據庫(經過R導入數據庫比較耗時,推薦用其餘方式導入),再經過加載數據庫包經過dbGetQuery()讀取數據。dbReadTable()讀取所有數據,效率較差,不推薦。

相關文章
相關標籤/搜索