使用dplyr操作數(shù)據(jù)框
關(guān)于dplyr的基本操作我已經(jīng)寫過很多筆記了,不再贅述,想學(xué)習(xí)的讀者請(qǐng)參閱下面幾篇文章,這部分我只挑沒接觸過的學(xué)習(xí)下。
- r<-基礎(chǔ)|分析】初學(xué)者學(xué)習(xí)tidyverse
- 【r<-數(shù)據(jù)分析】使用dplyr(1):介紹與filter操作及后續(xù)
- 高級(jí)操作:【r<-高級(jí)|dplyr】dplyr編程,quote與unquote
與data.table類似,dplyr也提供了do()函數(shù)來對(duì)每組數(shù)據(jù)進(jìn)行任意操作。
例如將diamonds按cut分組,每組都按log(price) ~ carat擬合一個(gè)線性模型。和data.table不同的是,我們需要為操作指定一個(gè)名稱,以便將結(jié)果存儲(chǔ)在列中。而且do()表達(dá)式不能直接在分組數(shù)據(jù)的語義下計(jì)算 ,我們需要使用.來表示數(shù)據(jù)。
data("diamonds", package = "ggplot2")
models = diamonds %>%
group_by(cut) %>%
do(lmod = lm(log(price) ~ carat, data = .))
models
#> Source: local data frame [5 x 2]
#> Groups: <by row>
#>
#> # A tibble: 5 x 2
#> cut lmod
#> * <ord> <list>
#> 1 Fair <S3: lm>
#> 2 Good <S3: lm>
#> 3 Very Good <S3: lm>
#> 4 Premium <S3: lm>
#> 5 Ideal <S3: lm>
注意結(jié)果創(chuàng)建了一個(gè)新列,該列不是典型的原子向量,每個(gè)元素都是模型的結(jié)果,包含線性回歸對(duì)象的列表。我們可以通過索引來提取模型結(jié)果:
models$lmod[[1]]
#>
#> Call:
#> lm(formula = log(price) ~ carat, data = .)
#>
#> Coefficients:
#> (Intercept) carat
#> 6.78 1.25
在需要完成高度定制的操作時(shí),do()的優(yōu)勢(shì)非常明顯。下面舉例。
假如我們需要分析toy_tests數(shù)據(jù),要對(duì)每種產(chǎn)品的質(zhì)量和耐久性進(jìn)行匯總。如果只需要樣本數(shù)最多的3個(gè)測(cè)試記錄,并且每個(gè)產(chǎn)品的質(zhì)量和耐久性是經(jīng)樣本數(shù)加權(quán)的平均數(shù),下面是做法。
toy_tests %>%
group_by(id) %>%
arrange(desc(sample)) %>%
do(head(., 3)) %>%
summarise(
quality = sum(quality * sample) / sum(sample),
durability = sum(durability * sample) / sum(sample)
)
#> # A tibble: 2 x 3
#> id quality durability
#> <chr> <dbl> <dbl>
#> 1 T01 9.32 9.38
#> 2 T02 9.04 8.34
為了查看中間結(jié)果,可以運(yùn)行do()之前的代碼:
toy_tests %>%
group_by(id) %>%
arrange(desc(sample))
#> # A tibble: 8 x 6
#> # Groups: id [2]
#> id date sample quality durability ym
#> <chr> <int> <int> <int> <int> <chr>
#> 1 T01 20160405 180 9 10 201604
#> 2 T01 20160302 150 10 9 201603
#> 3 T01 20160502 140 9 9 201605
#> 4 T01 20160201 100 9 9 201602
#> 5 T02 20160403 90 9 8 201604
#> 6 T02 20160502 85 10 9 201605
#> 7 T02 20160303 75 8 8 201603
#> 8 T02 20160201 70 7 9 201602
