看板 R_Language 關於我們 聯絡資訊
這章將要繼續上章未完的dplyr 以下是這章主要內容: A. 取唯一列:distinct, data.table:::unique B. 列行運算:rowwise, plyr:::colwise C. 值映射(對應修改):plyr:::mapvalues, plyr:::revalue D. 其他函數:summarise_each, mutate_each E. 特殊函數:plyr:::here F. function with underscore suffix 1. 取唯一列 我在第一章 data.table提過 unique distinct是一樣的方法 就從data.table:::unique的例子開始 ` R DT = data.table(A = rbinom(5, 1, 0.5), B = rbinom(5, 1, 0.5)) # A B # 1: 0 0 # 2: 0 1 # 3: 1 0 # 4: 0 1 # 5: 0 0 unique(DT) # A B # 1: 0 0 # 2: 0 1 # 3: 1 0 distinct(DT) # A B # 1: 0 0 # 2: 0 1 # 3: 1 0 unique(DT, by = "A") # A B # 1: 0 0 # 2: 1 0 distinct(DT, A) # A B # 1: 0 0 # 2: 1 0 ` 但是如mutate, filter等函數 distinct也可以給由變數組成的其他條件來做取唯一列的動作 給個簡單例子: ` R distinct(DT, A*B) # A B A * B # 1: 0 0 0 ` 2. 列行運算 mutate提供了列運算的函數 rowwise 雖然沒有apply好寫,不過效率確實好上不少 至少在chain上可以比較輕易地套用了 要介紹rowwise,還需要介紹do這個函數 do提供一些廣泛的運算方式 像是你可以根據不同變數設立模型如範例所示 ` R set.seed(100) DF = data.frame(A = sample(1:5, 50, TRUE), y = rnorm(50), x = rnorm(50)) models = DF %>% group_by(A) %>% do(model = lm(y ~ x, data = .)) models %>% summarise(mse = mean(model$residuals**2)) # mse # 1 0.07560431 # 2 0.03617592 # 3 0.71000090 # 4 0.35385491 # 5 1.39799410 DT = data.table(A = sample(1:5, 50, TRUE), y = rnorm(50), x = rnorm(50)) models = group_by(DT, A) %>% do(model = lm(y ~ x, data = .)) models %>% rowwise %>% summarise(mse = mean(model$residuals**2)) # mse # 1 0.8953635 # 2 0.3954457 # 3 0.1469698 # 4 0.6303710 # 5 0.2966472 ` data.table出來的結果不會自動group_by row 要自己手動加入rowwise,這點需要注意 do應該有更多應用,需要各位好好開發。 再來,給一個rowwise的應用: ` R set.seed(100) (DT = data.table(A = rnorm(5), B = rnorm(5), C = rnorm(5))) # A B C # 1: -0.50219235 0.3186301 0.08988614 # 2: 0.13153117 -0.5817907 0.09627446 # 3: -0.07891709 0.7145327 -0.20163395 # 4: 0.88678481 -0.8252594 0.73984050 # 5: 0.11697127 -0.3598621 0.12337950 DT %>% rowwise %>% do(k = c(.$A, .$B, .$C)[between(c(.$A, .$B, .$C), 0, 1)]) %>% summarise(size = length(k), sums = sum(k)) # size sums # 1 2 0.4085162 # 2 2 0.2278056 # 3 1 0.7145327 # 4 2 1.6266253 # 5 2 0.2403508 ` colwise提供每一行的做一個動作的方法 其實等同於你用sapply做 只是它還可以讓你選擇你要做的column去做 簡單例子如下: ` R set.seed(100) (DT = data.table(A = rnorm(5), B = rnorm(5), C = rnorm(5))) # A B C # 1: -0.50219235 0.3186301 0.08988614 # 2: 0.13153117 -0.5817907 0.09627446 # 3: -0.07891709 0.7145327 -0.20163395 # 4: 0.88678481 -0.8252594 0.73984050 # 5: 0.11697127 -0.3598621 0.12337950 colwise(function(x) c(mean(x), sd(x)))(DT) # A B C # 1 0.1600685 0.1890685 -0.6537084 # 2 0.8140039 0.7824803 0.5610936 colwise(function(x) c(mean(x), sd(x)), .cols = .(A, B))(DT) # A B # 1 0.1600685 0.1890685 # 2 0.8140039 0.7824803 f = function(x) quantile(x, c(0.05, 0.95)) colwise(f)(DT) # A B C # 1 -0.4175373 -0.7765657 -0.1433299 # 2 0.7357341 0.6353522 0.6165483 ` 3. 值映射(對應修改) 這一節要介紹兩個很好用的函數 plyr:::mapvalues, plyr:::revalue 這兩個函數再處理資料時一定很常用到 我們再整理資料時,有時候會遇到奇異值 我們要把它改成我們想要的值時 大部分人應該都會遇到這個問題 或是有時候我們需要組別整併時也會遇到 給一個簡單的example ` R DT = data.table(col1 = sample(c("A", "B", "N"), 30, TRUE), col2 = sample(c("A1", "B3", "C4", "U9", "Z5"), 30, TRUE), col3 = sample(-2:2, 30, TRUE)) DT2 = copy(DT) ## example 1 - 當初keyin資料出問題,col1出現了"N"這個值,我們要通通改成NA ## 此處提供數種方法做 set(DT, which(DT$col1 == "N"), "col1", NA) DT2 %>% mutate(col1 = ifelse(col1 == "N", NA, col1)) # transform同理 DT2 %>% mutate(col1 = revalue(col1, c(N = NA))) DT2 %>% mutate(col1 = mapvalues(col1, "N", NA)) ## example 2 - 我們想要把col2做調整 A1 改成 B3, U9改成Z5 ## 這裡就直接提供用revalue以及mapvalues的方法 DT2 %>% mutate(col2 = revalue(col2, c(A1 = "B3", U9 = "Z5"))) DT2 %>% mutate(col2 = mapvalues(col2, c("A1", "U9"), c("B3", "Z5"))) ## example 3 - 當初keyin時不小心搞錯col3的-2跟2的正負號,我們要把-2跟2做互換 DT2 %>% mutate(col3 = mapvalues(col3, c(-2, 2), c(2, -2))) ` 最後提示幾個重點, revalue可以用在factor跟character上面,不能用在數值上 mapvalues可以用在integer, double跟character上面,factor要先轉chr 4. 其他函數 這兩個函數 summarise_each, mutate_each,我自己也很少用 我提供一些例子做操作,先用簡單的例子 ` R DT = data.table(X = rnorm(100), Y = rnorm(100)) DT %>% summarise_each(funs(c(median(.), mean(.)))) # X Y # 1: -0.02923809 0.08238550 # 2: -0.09154615 0.05153845 DT = data.table(X = c(3,2), Y = c(1, 4)) DT %>% mutate_each(funs(half = . / 2)) # X Y # 1: 1.5 0.5 # 2: 1.0 2.0 ` 這例子只是很簡單的介紹他們的功能 可能需要時間來累積看看是否有什麼好方法去用這兩個函數 5. 特殊函數 介紹一個我覺得很有趣的函數 here here可以幫助你再使用sapply系列時 可以使用mutate等 提一個簡單的例子 ` R DTs = resplicate(5, data.table(A = rnorm(5)), simplify = FALSE) DTs = lapply(DTs, here(mutate), Asq = A**2) ` 6. function with underscore suffix 本章最後一個重點 怎麼使用像是filter_, select_, mutate_, ...這些以_結尾的function 這些以_結尾的function提供使用者使用string作為input 中間執行的過程透過 lazyeval 來執行 (其實dplyr大部分函數都透過這個套件) 來看幾個簡單的例子 ` R DT = data.table(A = rnorm(5), B = rnorm(5)) DT %>% select_("A") DT %>% select(A) DT %>% mutate(C = A*B) (DT2 = DT %>% mutate_("A*B") %>% setnames("A*B", "C")) ` 這幾個例子應該可以很簡單的解釋有_的函數要怎麼使用 最後給個.dots的用法,這個代表說你可以製作適當的string放入 ` R DT = data.table(x = rnorm(100), y = rnorm(100)) (DT %<>% mutate_(.dots = c("x^2", "y^2")) %>% setnames(c("x^2", "y^2"), c("xsq", "ysq"))) DT %>% select_(.dots = c("y", "xsq")) ` 再給一個簡單的例子 ` R DT = data.table(x1 = rnorm(100), x2 = rnorm(100)) cmds = paste0("x", 1:2, "^2") newnames = c("xsq", "ysq") DT %<>% mutate_(.dots = cmds) %>% setnames(cmds, newnames)) ` 下一章應該會是最後一章了 主要內容是data.table中的 dcast跟melt 還有tidyr的 separate, spread, gather [關鍵字]: dplyr -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 223.138.206.65 ※ 文章網址: https://www.ptt.cc/bbs/R_Language/M.1437573669.A.FB6.html
vespar: 推 09/19 18:35