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

看板R_Language作者 (拒看低質媒體)時間10年前 (2015/01/13 21:44), 編輯推噓9(906)
留言15則, 10人參與, 最新討論串2/2 (看更多)
關於資料整理,我很想推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


01/13 21:45, , 2F
年會的影片有對dplyr做更詳細和更精彩的介紹FYI
01/13 21:45, 2F

01/13 21:55, , 3F
GOOD!
01/13 21:55, 3F

01/13 22:07, , 4F
推~今天剛好看到dplyr cheatsheet http://goo.gl/iXj4CN
01/13 22:07, 4F

01/13 22:08, , 5F
感謝提供cheatsheets,收入置底資源區
01/13 22:08, 5F

01/13 22:11, , 6F
為什麼不使用 summarise(mean(Solar.R)) ?
01/13 22:11, 6F

01/13 22:27, , 7F
因為一時沒想到,謝謝補充。ps.兩種方式輸出的格式不同
01/13 22:27, 7F

01/13 22:55, , 8F
太感謝了~想不到還能多學兩招
01/13 22:55, 8F

01/13 23:00, , 9F
原po想玩迴圈,應該用cpp做範例的XD
01/13 23:00, 9F

01/13 23:01, , 10F
只好麻煩樓上了(推)
01/13 23:01, 10F

01/13 23:02, , 11F
magrittr裡面有包一些取代[[的function
01/13 23:02, 11F

01/14 15:15, , 12F
01/14 15:15, 12F

01/14 20:04, , 13F
好文章! 推
01/14 20:04, 13F

01/15 08:15, , 14F
實用!
01/15 08:15, 14F

07/06 17:02, , 15F
真的很感謝Wush大,總是說明得很清楚!推推推
07/06 17:02, 15F
文章代碼(AID): #1KjI4e5S (R_Language)
討論串 (同標題文章)
文章代碼(AID): #1KjI4e5S (R_Language)