R語言之dplyr包常用函數(shù)方法示例學(xué)習(xí)
引言
文章和代碼已經(jīng)歸檔至【Github倉庫:https://github.com/timerring/dive-into-AI 】
這個包以一種統(tǒng)一的規(guī)范更高效地處理數(shù)據(jù)框。dplyr
包里處理數(shù)據(jù)框的所有函數(shù)的第一個參數(shù)都是數(shù)據(jù)框名。
下面以 MASS 包里的 birthwt 數(shù)據(jù)集為例,介紹 dplyr 包里常用函數(shù)的用法。該數(shù)據(jù)集來自一項關(guān)于新生兒低體重危險因素的病例對照研究。首先加載該數(shù)據(jù)集并查看其相關(guān)信息。
library(dplyr) data(birthwt, package = "MASS") # ??birthwt
數(shù)據(jù)集 birthwt 里一共包含 189 個研究對象、10 個變量。其中結(jié)果變量 bwt 是新生兒的體重(單位:g),變量 low 是將 bwt 的取值以 2500g 為分點轉(zhuǎn)換成的一個二分類變量。其余 8 個變量均為預(yù)測變量,包括孕婦的年齡(age)、種族(race)、吸煙狀況(smoke)、高血壓史(ht)等。
1.使用 filter( ) 和 slice( ) 篩選行
函數(shù) filter()
可以基于觀測值篩選數(shù)據(jù)框的一個子集。第一個參數(shù)是數(shù)據(jù)框名,第二個參數(shù)以及隨后的參數(shù)是用來篩選數(shù)據(jù)框的表達式。
例如,篩選數(shù)據(jù)框里年齡大于 35 歲的對象的所有記錄:
filter(birthwt, age > 35)
函數(shù) filter ( ) 里可以用逗號分隔多個條件。使用下面的命令將會選擇選擇年齡大于 35 歲,并且出生體重小于 2500g 或者大于 4000g 的所有記錄,因為記錄較多,這里只顯示了前 10 行。
head(filter(birthwt, age > 35, bwt < 2500 | bwt > 4000),10)
函數(shù) slice( )
可以按照行號選擇指定的行。例如,下面的命令選擇數(shù)據(jù)集里面的第 2 行到第 5 行。
slice(birthwt, 2:5)
2.使用 arrange( ) 排列行
有時候我們想要將數(shù)據(jù)框的記錄按照某個變量進行排序,函數(shù) arrange()
可以實現(xiàn)這個功能。下面的命令將數(shù)據(jù)框按照變量 bwt 的值從小到大進行排序后顯示:
arrange(birthwt, bwt) # 默認升序
在上面的輸出中,第 6 行和第 7 行的變量 bwt 的值都是 1588,在這種情況下如果還想將數(shù)據(jù)框按照第二個變量排序,只需要在函數(shù) arrange( )
里加上第二個變量即可。例如,下面的命令將數(shù)據(jù)框按照變量 bwt 的值從小到大排序,在 bwt 取值相等的情況下再按照第二個變量 age 的值從小到大排序。
arrange(birthwt, bwt, age)
如果想把數(shù)據(jù)框按照某個變量的值從大到小進行排序,可以借助函數(shù) desc( )
實現(xiàn)。
arrange(birthwt, desc(bwt)) # 等價于 arrange(birthwt, - bwt)
3. 使用 select( ) 選擇列
函數(shù) select( )
用于選擇數(shù)據(jù)框中的列(變量)。
# 下面的命令選擇數(shù)據(jù)框里面的 bwt、age、race 和 smoke 這 4 個變量組成新的數(shù)據(jù)框。 select(birthwt, bwt, age, race, smoke)
請注意,MASS 包里有一個同名函數(shù) select( ),如果同時加載了 dplyr 包和 MASS 包,R 會默認使用較后加載的包里的函數(shù)。為了避免混淆,我們可以使用符號 ::
特別指明使用某一個包里的函數(shù),例如 dplyr::select( )
。之后我們將會對函數(shù) select( ) 作進一步介紹。
4.使用 mutate( ) 添加新變量
函數(shù) mutate( )
用于在數(shù)據(jù)框中創(chuàng)建新的變量。下面的命令將數(shù)據(jù)集 birthwt 里的變量 lwt(單位:lb)乘以系數(shù) 0.4536 后生成新的變量 lwt.kg(1lb ≈ 0.4536kg)。
# 當(dāng)然如果想要用新變量替換原來的變量,只需把新變量命名為原來的變量名: mutate(birthwt, lwt.kg = lwt*0.4536)
5.使用 summarise( ) 計算統(tǒng)計量
函數(shù) summarise( ) 可以用于計算數(shù)據(jù)框中某個變量的指定統(tǒng)計量。
例如,計算變量 bwt 的樣本均值和樣本標準差:
summarise(birthwt, Mean.bwt = mean(bwt), Sd.bwt = sd(bwt))
6. 使用 group\_by( ) 拆分數(shù)據(jù)框
函數(shù) group_by( )
可以將數(shù)據(jù)框按照某一個或某幾個分類變量拆分成多個數(shù)據(jù)框。例如:
group_by(birthwt, race) str(group_by(birthwt, race)) # ============ 輸出 ============= grouped_df [189 × 10] (S3: grouped_df/tbl_df/tbl/data.frame) $ low : int [1:189] 0 0 0 0 0 0 0 0 0 0 ... $ age : int [1:189] 19 33 20 21 18 21 22 17 29 26 ... $ lwt : int [1:189] 182 155 105 108 107 124 118 103 123 113 ... $ race : int [1:189] 2 3 1 1 1 3 1 3 1 1 ... $ smoke: int [1:189] 0 0 1 1 1 0 0 0 1 1 ... $ ptl : int [1:189] 0 0 0 0 0 0 0 0 0 0 ... $ ht : int [1:189] 0 0 0 0 0 0 0 0 0 0 ... $ ui : int [1:189] 1 0 0 1 1 0 0 0 0 0 ... $ ftv : int [1:189] 0 3 1 2 0 0 1 1 1 0 ... $ bwt : int [1:189] 2523 2551 2557 2594 2600 2622 2637 2637 2663 2665 ... - attr(*, "groups")= tibble [3 × 2] (S3: tbl_df/tbl/data.frame) ..$ race : int [1:3] 1 2 3 ..$ .rows: list<int> [1:3] .. ..$ : int [1:96] 3 4 5 7 9 10 15 16 18 20 ... .. ..$ : int [1:26] 1 17 29 30 31 33 35 41 43 70 ... .. ..$ : int [1:67] 2 6 8 11 12 13 14 19 21 24 ... .. ..@ ptype: int(0) ..- attr(*, ".drop")= logi TRUE
函數(shù) group\_by( ) 不會改變數(shù)據(jù)框的外觀,而會改變它與其他 dplyr 動詞函數(shù)的作用方式 。因此,上面的輸出結(jié)果看上去和原來的數(shù)據(jù)框沒有什么差別,但實質(zhì)上是不同的。最本質(zhì)的差別是多了一個分組屬性(Groups),即上面的結(jié)果包含了 3 個數(shù)據(jù)框,分別對應(yīng)于變量 race 的 3 個類別。
你還可能注意到上面輸出對象的格式(grouped_df [189 × 10] (S3: grouped_df/tbl_df/tbl/data.frame)
)。與 R/Rstudio 上不同,notebook 這里把它顯示成了 A grouped_df: 189 × 10
(而非 # A tibble: 189 x 10
),實際它仍然包含 tibble(注意其中的 - attr(*, "groups")= tibble [3 × 2] (S3: tbl_df/tbl/data.frame)
)。另外,它沒有顯示 Groups
屬性信息,實際應(yīng)為 # Groups: race [3]
。
tibble 是 tidyverse 系列包(包括 dplyr 包)提供的一種類似數(shù)據(jù)框的格式。相對于傳統(tǒng)的數(shù)據(jù)框,tibble 在很多方面具有優(yōu)勢,感興趣的讀者可以參閱函數(shù) tibble( ) 的幫助文檔。我們可以用函數(shù) as_tibble( )
將傳統(tǒng)的數(shù)據(jù)框轉(zhuǎn)換為 tibble,也可以用函數(shù) as.data.frame( )
將 tibble 轉(zhuǎn)換成傳統(tǒng)的數(shù)據(jù)框。
as_tibble(birthwt)
下面我們將會看到,把函數(shù) group\_by( ) 和 summarise( ) 聯(lián)合使用能方便地對變量進行分組統(tǒng)計。
7. 使用傳遞符 %>% 組合多個操作
我們經(jīng)常需要對一個數(shù)據(jù)框做一系列的操作,后面一個操作的輸入需要用前一個操作的輸出結(jié)果。
# 第一步把數(shù)據(jù)框 birthwt 里面的變量 race 轉(zhuǎn)換成因子并給各個水平添加標簽,把新的數(shù)據(jù)框命名為 birthwt1 birthwt1 <- mutate(birthwt, race = factor(race, labels = c("white", "black", "other"))) # 第二步把數(shù)據(jù)框 birthwt1 按照變量 race 分組,把分組后的對象命名為 birthwt.group; birthwt.group <- group_by(birthwt1, race) # 第三步對于分組對象 birthwt.group 計算各組中變量 bwt 的平均值。 summarise(birthwt.group, mean(bwt))
這種方法的最大缺點是需要為每個中間結(jié)果建立一個變量。在很多情況下,比如在上面的示例中,這些中間變量其實是沒有什么實際意義的。我們需要給這些中間變量命名,而且這些中間變量會保存在工作空間中占用內(nèi)存。傳遞操作符 %>%
將該符號之前的對象傳遞給符號后面的函數(shù)并作為函數(shù)的第一個參數(shù)值。例如:
c(2, 4, 6, 8) %>% matrix(nrow = 2)
因為 dplyr 包里面的函數(shù)第一個參數(shù)總是數(shù)據(jù)框,所以這些函數(shù)配合傳遞操作符處理數(shù)據(jù)框非常方便。下面用傳遞操作符改寫上面的命令:
birthwt %>% mutate(race = factor(race, labels = c("white", "black", "other"))) %>% group_by(race) %>% summarise(mean(bwt))
上述代碼的重點在于動詞函數(shù),而不是函數(shù)中的參數(shù)。在閱讀這一串代碼組合時,可以將它們當(dāng)成一系列的規(guī)定動作。
項目實戰(zhàn)
epiDisplay
包里的數(shù)據(jù)集 Planning
來自 20 世紀 80 年代中期泰國的一項計劃生育調(diào)查研究,請通過其幫助文件查看數(shù)據(jù)信息并整理該數(shù)據(jù)集。
library(epiDisplay) data(Planning) print(des(Planning)) names(Planning) <- tolower(names(Planning)) # 把變量名變?yōu)樾懽帜? summary(Planning) table(duplicated(Planning$id)) # 查看是否有重復(fù)id; # FALSE TRUE # 250 1 which(duplicated(Planning$id)) # 找出重復(fù)id的行號;把 XXXXXX 替換成正確的代碼 # 216 Planning$id # 驗證下 Planning$id[216] <- 216 # 修正重復(fù)id; library(dplyr) Planning <- mutate( Planning, relig = ifelse(relig == 9, NA, relig), # 將變量relig中的9變成NA ped = ifelse(ped == 0 | ped == 9, NA, ped), # 將變量ped中的0和9變成NA income = ifelse(income == 9, NA, income), # 將變量income中的9變成NA am = ifelse(am == 99, NA, am), # 將變量am中的99變成NA reason = ifelse(reason == 9, NA, reason), # 將變量reason中的9變成NA bps = ifelse(bps == 0 | bps == 999, NA, bps), # 將變量bps中的0和999變成NA bpd = ifelse(bpd == 0 | bpd == 999, NA, bpd), # 將變量bpd中的0和999變成NA wt = ifelse(wt == 0 | wt > 99, NA, wt), # 將變量wt中的0和大于99的值變成NA ht = ifelse(ht == 0 | ht > 300, NA, ht) # 將變量ht中的0和大于300的值變成NA; )
以上就是R語言之dplyr包常用函數(shù)方法示例學(xué)習(xí)的詳細內(nèi)容,更多關(guān)于R語言dplyr包函數(shù)方法的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
R語言-如何循環(huán)讀取excel并保存為RData
這篇文章主要介紹了R語言循環(huán)讀取excel并保存為RData的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-04-04R語言 數(shù)據(jù)表匹配和拼接 merge函數(shù)的使用
這篇文章主要介紹了R語言 數(shù)據(jù)表匹配和拼接 merge函數(shù)的使用說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-03-03R語言-生成頻數(shù)表和列聯(lián)表crosstable函數(shù)介紹
這篇文章主要介紹了R語言-生成頻數(shù)表和列聯(lián)表crosstable函數(shù)介紹,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-04-04