→ locka: 代碼N裡面有可能出現033開頭的值嗎? 09/07 14:06
代碼1 ~ 代碼N 都可能出現O33開頭的值
N的數量不固定
用 filter_at 可以抓 column name 裡面有"代碼"開頭的columns
另外還可能有其他開頭不是"代碼"的columns
這些columns不可列入檢查
→ andrew43: 我覺得先把pattern字串寫在一個向量,用for loop就好了 09/07 17:15
→ andrew43: 最後再cbind或join 09/07 17:15
這個code只在代碼1比對 O33, 在代碼2比對 O34。
在代碼2出現O33就不行了。
當然寫成巢狀 for loop也可以
但是這樣實現的話
使用 filter_at 的簡潔度與可讀性可能更好些
而且在N會變動的情況下
巢狀 for loop 會更麻煩些
※ 編輯: daze (114.40.18.158 臺灣), 09/07/2020 18:14:49
→ andrew43: 那只要寫出合適的pattern還是可以不改結構的。 09/07 18:35
→ andrew43: N會變動應該不麻煩,用ncol()幫忙一下。 09/07 18:36
推 JuanMaestrow: 先gather起來變成只有一個column是代碼。mutate用st 09/08 13:42
→ JuanMaestrow: r_detect搭配regex。做完再speead出去就可以了 09/08 13:42
更之前有試著用 reshape2::melt/dcast
行為跟 tidyr::gather/spread 應該很類似
不過有個問題是 melt 後 dataframe 會變大好幾倍
比較小的檔案可以這麼做,但6G的檔案變大10倍,記憶體就爆了
當時的做法是把某些暫時不用的 column 抽掉先把檔案瘦身
跑完 melt/dcast 之後再 join 回去
但這樣當然比較麻煩,又容易出錯
目前處理的檔案大小,最大就 10G 左右
剛好落在用 filter_at 不會爆而用 melt 就會爆的狀態
filter_at 在效能上對我來說其實剛好夠用,能用的參數也算方便
但 filter_at 為了 filter,應該本來就會為每一 row 產生一個邏輯值
我主要的困擾是
希望有現成的類似函式可以直接產生該邏輯值寫入新 column
而不必使用 filter_at 生成新 dataframe 再 join 回去
從而可以直接對 patterns list 做 lapply
※ 編輯: daze (114.40.18.158 臺灣), 09/08/2020 16:53:57
做兩次 lapply 再 cbind,最後把 column name 改掉。
缺點是可能過兩個月我就搞不清這段code的作用了。
require(dplyr)
df<- read.csv(...)
pattern.list <- c("^O33", "^O34")
CNames<-colnames(df)
df<-df %>% cbind( lapply( pattern.list, function(y) Reduce("|",
lapply(select(.,starts_with("代碼")), function(x) grepl(y, x)))))
colnames(df)<-c(CNames,pattern.list)
※ 編輯: daze (114.40.18.158 臺灣), 09/08/2020 21:56:34
這樣似乎稍微好一點...
cbind(df, lapply(pattern.list, function(x) df %>% rowwise() %>% summarise(
(sum(grepl( x, across(starts_with("代碼"))))>0))))
但這樣不是非常有效率
跑 1.7M rows, 在 6個 column中比對1個pattern, 大概要 3~4 分鐘
用一開始的 filter_at 實現同樣的比對則要花... 3 秒鐘。
※ 編輯: daze (114.40.18.158 臺灣), 09/08/2020 23:32:04
推 intotherain: 用across+1 很精煉的寫法耶 09/09 09:36
推 JuanMaestrow: 我沒有叫你melt阿。gather跟spread好很多。你不要 09/09 20:06
→ JuanMaestrow: 自己跑去用melt 09/09 20:06
試著讀了一個約 5G 的 CSV 檔進來 (12568899 rows x 43 columns)
Rstudio 顯示 data.frame 大小是 6259133200 bytes
將 6 個代碼欄 gather 成一個
data.frame 大小變成 22696429616 bytes
在工作管理員中, Rsession.exe 的記憶體用量則約 28G
電腦開始 lag, 畢竟實體記憶體只有 32G
把 R 重啟後,用 melt 做同樣的操作
data.frame 大小變成 22394776472 bytes
電腦仍然開始 lag
所謂 gather 比 melt 好很多,具體是指哪方面?
※ 編輯: daze (36.237.70.94 臺灣), 09/09/2020 23:24:29
推 cywhale: 我不知道有無誤解題意 如果pattern是有限個 比如 09/11 12:28
→ cywhale: pat=c("033","034","035"); chkhead<-function(x){matrix 09/11 12:34
→ cywhale: pat%in%substr(x,1,3)),ncol=3)} 用apply(df,1,chkhead) 09/11 12:36
→ cywhale: 如果有速度需求可以拆平行做或者分批 如果記憶體不夠?.. 09/11 12:38
※ 編輯: daze (114.39.55.253 臺灣), 09/13/2020 22:00:23
※ 編輯: daze (114.39.55.253 臺灣), 09/14/2020 23:53:52