Re: [問題] 如何更有效率的整理data的問題?
※ 引述《phil5566 (5566)》之銘言:
: [問題類型]:
: 效能諮詢(我想讓R 跑更快)
: [軟體熟悉度]:
: 新手(沒寫過程式,R 是我的第一次)
: [問題敘述]:
: 小弟自己產生一組data叫做"T"的矩陣,
: 想把其中"T"的第5行(T[,5])和第6行(T[,6])的數據,
: 挑出來整理成一個120X3的矩陣,假設叫"G",
: T[,5]的數值有10,16,22,28,34,40,6個可能,
: T[,6]的數值有0.5,1.5,2.5,.........,19.5和inf的可能,
: 整理方法:
: G的第一行(G[,1]):放0.5,1.5,....,19.5(20個數,6個循環,共120個)
: G的第二行(G[,2]):放的東西比較麻煩,即
: T[,5]=10的情況下,對應到T[,6]那些0.5,1.5,.....,19.5,inf的數值
: 計算他們的累積比率,假設T[,5]=10,有100筆data,
: T[,5]=10且T[,6]<=0.5(或者T[,6]<=1)有22筆,
: 則它算出的累積比率為22/100=0.22,依此類推...,
: 算到T[,5]=10且T[,6]<=19.5(或者T[,6]<=20)的累積比率
: 共20個數字放到G[1:20,2],重複以上模式處理T[,5]=16,22,28,34,40的情形
: 分別放到G[21:40,2],G[61:80,2],.....,G[101:120,2]
: G的第三行(G[,3]):G[1:20,3]放10,G[21:40,3]放16,......G[101:120,3]放40
: ________________________________________________________________________
: 小弟之前是用table函數處理,
: 直接table(T[,5],T[,6])得到分類結果
: 再分別計算累積比率,沒用到廻圈,
: 但考慮到"假設T[,6]可能沒有出現5.5的情況",
: table函數分類後就不會有5.5的這個分類,
: 所以小弟又重新寫,用兩個廻圈來整理data,
: 第一個廻圈是在處理G[,1]和G[,3],第二個廻圈在處理G[,2]
: 以下附上code範例,
: 想請教版上各位高手,大大有沒有更漂亮,快速的處理方法,
: 指教了,謝謝~
: [程式範例]:
: http://pastebin.com/bw0C2YNJ
: [環境敘述]:
: R x64 3.3.1
: [關鍵字]:
: data整理
# generage T[,5]跟T[,6]
targetMat <- cbind(sample(c(10,16,22,28,34,40), 2e4, TRUE),
sample(c(seq(0.5,19.5,by = 1), Inf), 2e4, TRUE))
# 取unique的T[,5]
g1 <- unique(targetMat[ , 1])
# 取T[,6] min ~ max(除去Inf),間隔1的序列,共20個
g2 <- seq(min(targetMat[ , 2]), max(targetMat[is.finite(targetMat[,2]), 2]),
by = 1)
# 展開g1跟g2,並加一行轉成矩陣
outputDF <- expand.grid(g1, g2)
outputMat <- as.matrix(cbind(outputDF[order(outputDF$Var1, outputDF$Var2), ],
0))
# 用tapply計算每一個g1, g2對應的次數,第一個input隨意放即可,沒用到,我這裡放1
resMat <- tapply(rep(1, nrow(targetMat)),
list(targetMat[,1], targetMat[, 2]), length)
# 用cumsum算出累積次數,再用sweep算累積比率
# 最後再把矩陣拉直,變成outputMat的第三行
outputMat[ , 3] <- as.vector(sweep(apply(resMat[ , 1:20], 1, cumsum), 2,
rowSums(resMat), `/`))
最後一行可能要花時間消化一下,先從
apply(resMat[ , 1:20], 1, cumsum) 看起
然後去看sweep用法
看一下 rowSums(resMat) 代表的意義
組合起來就是你要的累積比率
另外要注意我有先對outputMat排序,才能直接放進去
再寫的時候要注意順序錯了,塞進去的結果就會不對了
--
R資料整理套件系列文:
magrittr #1LhSWhpH (R_Language) https://goo.gl/72l1m9
data.table #1LhW7Tvj (R_Language) https://goo.gl/PZa6Ue
dplyr(上.下) #1LhpJCfB,#1Lhw8b-s (R_Language) https://goo.gl/I5xX9b
tidyr #1Liqls1R (R_Language) https://goo.gl/i7yzAz
pipeR #1NXESRm5 (R_Language) https://goo.gl/zRUISx
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 118.170.46.59
※ 文章網址: https://www.ptt.cc/bbs/R_Language/M.1485855748.A.626.html
推
01/31 22:21, , 1F
01/31 22:21, 1F
→
01/31 22:23, , 2F
01/31 22:23, 2F
→
01/31 22:24, , 3F
01/31 22:24, 3F
→
01/31 22:26, , 4F
01/31 22:26, 4F
對,相比X再比Y,預設是increasing or ascending排序
推
01/31 22:29, , 5F
01/31 22:29, 5F
→
01/31 22:30, , 6F
01/31 22:30, 6F
tapply(x, y, fun):
x是目標向量
y可以是向量或是list,向量長度要和x長度相同
若是list,每個元素的長度都要和x長度相同
fun是每一組要做的動作
舉例:
tapply(1:6, rep(1:2, 3), mean)
x y
1 1
2 2
3 1 就是y=1的對應的x取mean跟 1 2 (這個是group)
4 2 y=2的對應的y取mean => 3 4 (這個是value)
5 1
6 2
如果第二個是list
tapply(1:6, list(rep(1:2,3), rep(1:3, each=2)), mean)
x y1 y2
1 1 1
2 2 1
3 1 2
4 2 2
5 1 3
6 2 3
這樣就是 y1=1, y2=1的一組,y1=2, y2=1的一組, ... 分別取mean
這些其實在?tapply都可以找到,不需要google
我覺得看R程式範例去學習也是很重要的,要自己想辦法學習阿~~
我的程式碼應該就簡單懂了,根據g1跟g2的分組計算每組的length
推
01/31 22:34, , 7F
01/31 22:34, 7F
→
01/31 22:35, , 8F
01/31 22:35, 8F
→
01/31 22:38, , 9F
01/31 22:38, 9F
→
01/31 22:40, , 10F
01/31 22:40, 10F
對不起,我考慮的不夠周到,那你只能寫死了
g2 <- seq(0.5, 19.5, by = 1)
推
02/01 01:13, , 11F
02/01 01:13, 11F
最後順便回答你前一篇的問題
benchmark是評比的意思
你可以把程式分段去看執行時間
或是 直接使用profvis這個套件
可以比較容易抓出程式瓶頸的部分
再根據瓶頸部份去改善
柏拉圖法則:80%的速度瓶頸來自20%的程式碼
※ 編輯: celestialgod (118.170.46.59), 02/01/2017 02:05:39
推
02/01 18:34, , 12F
02/01 18:34, 12F
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 3 之 3 篇):