Re: [問題] 資料處理速率緩慢

作者: celestialgod (天)   2017-04-29 20:33:17
※ 引述《tan800630 (天ㄦ)》之銘言:
: [問題類型]:
:
: 效能諮詢(我想讓R 跑更快)
:
: [軟體熟悉度]:
:
: 使用者(已經有用R 做過不少作品)
: [問題敘述]:
:
: 各位版上的前輩好,最近自己在玩臉書粉絲專頁的資料,目前想要統計
: 某段時間的Po文中總共有哪些人按讚,每人的按讚次數,以及Po文時間,
: 目前已經先將粉絲專頁(柯文哲 哈)某一段時間的po文都抓下來並存成RData檔案,
: #直接抓getPost()的資料存進去
: 目前希望將檔案整理成 "ID","最早按讚文章日期","最後按讚文章日期","總共按讚次數"
: 的格式,目前使用的方式仍然是用迴圈逐次讀取每一個檔案並且記錄按讚者的
: 相關內容(我知道迴圈效率很低O_Q 自己嘗試使用apply系列但失敗)
: 然而由於按讚者眾多,目前照著我預設的方式會跑非常久,因此想請教各位有沒有
: 甚麼建議可以讓整個程式的處理效率更快速
: 再麻煩各位前輩指教~~~~~
:
: [程式範例]:
:
: 程式碼
: https://pastebin.com/e9WY2AjD
: 範例檔案下載處(放了三篇文章的檔案,請參考)
: http://doora.qiniudn.com/lH2Z7.rar
:
: [環境敘述]:
:
: R version 3.3.2 (2016-10-31)
: Platform: x86_64-w64-mingw32/x64 (64-bit)
: Running under: Windows 8.1 x64 (build 9600)
: locale:
: [1] LC_COLLATE=Chinese (Traditional)_Taiwan.950
: [2] LC_CTYPE=Chinese (Traditional)_Taiwan.950
: [3] LC_MONETARY=Chinese (Traditional)_Taiwan.950
: [4] LC_NUMERIC=C
: [5] LC_TIME=Chinese (Traditional)_Taiwan.950
: attached base packages:
: [1] stats graphics grDevices utils datasets methods base
: other attached packages:
: [1] Rfacebook_0.6.12 httpuv_1.3.3 rjson_0.2.15 httr_1.2.1
: loaded via a namespace (and not attached):
: [1] R6_2.2.0 tools_3.3.2 Rcpp_0.12.9
:
: [關鍵字]:
:
: 迴圈
後面有R code,不過我先說,我建議這種資料直接存到資料庫
一個表存POST,一個表存Like,一個表存Comment
每一個POST都存一個POST ID,Like跟Comment表再存的時候也要記得給一個post id
然後用SQL就可以輕鬆串出你要的結果了:
select b.from_id user_id, min(a.post_time) first_like,
max(a.post_time) last_like, count(a.post_time) count_like
from post_table a, like_table b
where 1=1
and a.post_id = b.post_id
group by b.from_id
但是要用R做的話大概是這樣:
library(pipeR)
library(data.table)
library(lubridate)
postDT <- lapply(list.files("lH2Z7", full.names = TRUE), function(fn){
load(fn)
data.table(post_time = parse_date_time(substring(post$post$created_time,
1, 19), "ymd HMS"), post$likes)
}) %>>% rbindlist
outDT <- list(
dcast(postDT, from_id + from_name ~ 1, min, value.var = "post_time") %>>%
setnames(".", "first"),
dcast(postDT, from_id + from_name ~ 1, max, value.var = "post_time") %>>%
setnames(".", "last"),
dcast(postDT, from_id + from_name ~ 1, length, value.var = "post_time") %>>%
setnames(".", "count")
) %>>%
Reduce(f = function(x, y) merge(x, y, by = c("from_id", "from_name")))
# 結果:
# from_id from_name first last count
# 1: 1000352350101347 王相現 2017-04-11 12:06:46 2017-04-13 14:31:01 3
# 2: 1000365193433309 Erica Wang 2017-04-13 14:31:01 2017-04-13 14:31:01 1
# 3: 1000465496719965 陳健男 2017-04-12 11:00:15 2017-04-12 11:00:15 1
# 4: 1001166286680917 Jolie Liaw 2017-04-12 11:00:15 2017-04-12 11:00:15 1
# 5: 1001188363348018 翁茂翔 2017-04-12 11:00:15 2017-04-13 14:31:01 2
dcast一定要吃到global environment宣告的函數(攤手
所以我就乖乖寫了,沒有用lapply配合assign宣告到.GlobalEnv
作者: tan800630 (天ㄦ)   2017-04-30 20:14:00
謝謝C大! 晚點試試看其實dplyr之前也摸過,但感覺還沒內化成第一時間會想到處理效率自己實在是不大會比較,看來之後還是要多觀摩

Links booklink

Contact Us: admin [ a t ] ucptt.com