精華區beta R_Language 關於我們 聯絡資訊
關於資料整理,我很想推dplyr這個套件, 以及magrittr所導入的pipeline語法。 借你的問題來跟大家分享一下如何用dplyr來解決這種問題 : 各位大大好,小弟在做coursera的作業時有一題要求把 : 一個給定的data.frame(叫做airquality)中某兩個向 : 量(Ozone和Temp)分別大於31和90時的第三個向量Solar.R : 的平均值是多少? ```r attach(airquality) library(dplyr) filter(airquality, !is.na(Ozone), !is.na(Temp)) %>% filter(Ozone > 31, Temp > 90) %>% `[[`("Solar.R") %>% mean ``` 前兩行載入資料和dplyr。 dplyr對於表格化的物件,如: data.frame data.table (當資料量大的時候,好用的套件) SQL database 中的table 提供了一致的「動作」來作資料整理。 常用的有: 選行: select, 同SQL select 選列: filter, 同SQL where 排序: arrange, 同SQL sort by 取獨特值: distinct, 同SQL distinct 更動值: mutate, 同SQL update 總結: summarise (可搭配group_by使用,類似SQL group by) 這裡第三行 filter(airquality, !is.na(Ozone), !is.na(Temp)) 表示從airquality中取出Ozone和Temp不是NA的列出來 第三行最後面的`%>%`是magrittr套件(dplyr會自動幫你載入它) 導入的一種`pipeline`方式的寫法。 他的功能在於,把前面的輸出結果,放到下一個函數的第一個參數 舉例來說,原本我們要這樣寫: df1 <- filter(airquality, !is.na(Ozone), !is.na(Temp)) df2 <- filter(df1, Ozone > 31, Temp > 90) 懶惰的人如我,可能會寫成 filter(filter(airquality, !is.na(Ozone), !is.na(Temp)), Ozone > 31, Temp > 90) 這樣可以略過中間的暫存變數df1,但是程式碼也變醜了 透過`%>%`,我們可以把上面兩行改成: filter(airquality, !is.na(Ozone), !is.na(Temp)) %>% # df1 filter(Ozone > 31, Temp > 90) # filter(df1, ...) 不但可以略過暫存變數,同時程式碼仍然看起清楚 最後利用`%>%`和`[[`達到取出行變數Solar.R 再用mean算出平均值。 這裡順便跟大家宣導一個小概念: R 中所有的東西都是「函數」,包含airquality[["Solar.R"]]這種語法, 實際上是`[[`(airquality, "Solar.R") 利用這樣的概念,再搭配`%>%`的威力,程式碼就寫的更爽了 : 後來我有發現可以用: : attach(data) : sub <- subset(data,Ozone > 31 & Temp > 90) : summary(sub) : 的方式求出Solar.R在符合上述兩個條件之下的平均值。 : 但一開始只是直覺地想要用for loop暴力算,但沒成功, : 想問板上是否可以用迴圈的方式算出來?以下是自己嘗試 : 的程式碼,附帶一提: : data[,1]是Ozone : data[,2]是Solar.R : data[,4]是Temp : [程式範例]: : add <- 0 : count <- 0 : for(i in 1:153){ : if(data[i,1]>31 & data[i,4]>90) : add <- add + data[i,2] #把符合條件的Temp值累加 : count <- count + 1 : } : mean <- add/count : 這裏遇到的問題是data[,1]含有NA值,所以我想把有NA值 : 的資料刪掉,於是先跑這個for loop: : for(i in 1:153){ : if(is.na(hw2[i,1])) : hw2[i,] <- NULL : } : 結果: : 錯誤在`[<-.data.frame`(`*tmp*`, i, , value = NULL) : : replacement has 0 items, need 6 : 不知道是類型不一樣,NULL不能隨便套用還是其他原因, : 總之先感謝各位大大把這篇看完QQ -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 118.161.35.149 ※ 文章網址: https://www.ptt.cc/bbs/R_Language/M.1421156648.A.15C.html
Wush978: 年會的影片有對dplyr做更詳細和更精彩的介紹FYI 01/13 21:45
ntme: GOOD! 01/13 21:55
cywhale: 推~今天剛好看到dplyr cheatsheet http://goo.gl/iXj4CN 01/13 22:07
Wush978: 感謝提供cheatsheets,收入置底資源區 01/13 22:08
memphis: 為什麼不使用 summarise(mean(Solar.R)) ? 01/13 22:11
Wush978: 因為一時沒想到,謝謝補充。ps.兩種方式輸出的格式不同 01/13 22:27
ToastCheng: 太感謝了~想不到還能多學兩招 01/13 22:55
obarisk: 原po想玩迴圈,應該用cpp做範例的XD 01/13 23:00
Wush978: 只好麻煩樓上了(推) 01/13 23:01
obarisk: magrittr裡面有包一些取代[[的function 01/13 23:02