Re: [問題] 擷取data.frame中的特定資料

作者: Wush978 (拒看低質媒體)   2015-01-13 21:44:05
關於資料整理,我很想推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
作者: Wush978 (拒看低質媒體)   2015-01-13 21:45:00
https://www.youtube.com/watch?v=JD1eDxxrur0年會的影片有對dplyr做更詳細和更精彩的介紹FYI
作者: ntme (one shot one kill)   2015-01-13 21:55:00
GOOD!
作者: cywhale (cywhale)   2015-01-13 22:07:00
推~今天剛好看到dplyr cheatsheet http://goo.gl/iXj4CN
作者: Wush978 (拒看低質媒體)   2015-01-13 22:08:00
感謝提供cheatsheets,收入置底資源區
作者: memphis (讓你喜歡這世界~)   2015-01-13 22:11:00
為什麼不使用 summarise(mean(Solar.R)) ?
作者: Wush978 (拒看低質媒體)   2015-01-13 22:27:00
因為一時沒想到,謝謝補充。ps.兩種方式輸出的格式不同
作者: ToastCheng (ToastCheng哥)   2015-01-13 22:55:00
太感謝了~想不到還能多學兩招
作者: obarisk (OSWALT)   2015-01-13 23:00:00
原po想玩迴圈,應該用cpp做範例的XD
作者: Wush978 (拒看低質媒體)   2015-01-13 23:01:00
只好麻煩樓上了(推)
作者: obarisk (OSWALT)   2015-01-13 23:02:00
magrittr裡面有包一些取代[[的function
作者: mnhjlopi (大雕)   2015-01-14 15:15:00
作者: squallscer (羽毛)   2015-01-14 20:04:00
好文章! 推
作者: nh2 (nh)   2015-01-15 08:15:00
實用!

Links booklink

Contact Us: admin [ a t ] ucptt.com