作者:黃天元,復旦大學博士在讀,目前研究涉及文本挖掘、社交網絡分析和機器學習等。希望與大家分享學習經驗,推廣並加深R語言在業界的應用。
郵箱:huang.tian-yuan@qq.com
本章講解如何使用summarise函數完成數據的匯總。在開講之前,我們需要理解,什麼叫做匯總。舉個例子,如果我們現在對學校的學生身高進行了測量,我們需要得到學生的平均身高,那麼我們把所有學生的身高加起來,除以學生的數量,得到身高平均值,這就完成了一個匯總計算。匯總計算的方式多種多樣,比如我們要得到最高的身高是多少,最低的身高是多少,身高是中位數是多少,這些都是匯總計算。
在數據表中,數據的匯總的實質就是:我們根據一列數據(本質來說是一個向量),得到一個值,來反映總體在這個屬性上的特徵。本章會用到R語言自帶cars數據集,下面我們先加載需要的包,並把cars轉化為tibble,存放在cars1變量中。它只包含兩列數據,第一列是汽車的即時速度,第二列是這個速度下要停止下來會繼續跑多遠。
1library(tidyverse)
2cars %>% as_tibble() -> cars1
3cars1
4## # A tibble: 50 x 2
5## speed dist
6## <dbl> <dbl>
7## 1 4 2
8## 2 4 10
9## 3 7 4
10## 4 7 22
11## 5 8 16
12## 6 9 10
13## 7 10 18
14## 8 10 26
15## 9 10 34
16## 10 11 17
17## # ... with 40 more rows
均值和中位數代表了數據的一般水平,是重要的衡量指標。下面我們看看如何匯總測試的平均值和中位數。
1#平均速度
2cars1 %>%
3 summarise(mean(speed))
4## # A tibble: 1 x 1
5## `mean(speed)`
6## <dbl>
7## 1 15.4
8#速度的中位數
9cars1 %>%
10 summarise(median(speed))
11## # A tibble: 1 x 1
12## `median(speed)`
13## <dbl>
14## 1 15
SQL代碼分別為:
<SQL> SELECT AVG(`speed`) AS `mean(speed)`
FROM `cars1`
<SQL> SELECT MEDIAN(`speed`) AS `median(speed)`
FROM `cars1`
注意,我們這裡沒有給最後的結果命名,因此結果中默認原來的值為命名,也就是說mean(speed)成為了列的名稱,事實上我們可以通過賦值來改變它,例子如下:
1cars1 %>%
2 summarise(speed_avg = mean(speed))
3## # A tibble: 1 x 1
4## speed_avg
5## <dbl>
6## 1 15.4
現在得到結果的名稱就變為speed_avg了,相應的SQL代碼如下所示:
<SQL> SELECT AVG(`speed`) AS `speed_avg`
FROM `cars1`
但是基本模式與上面一致,比如我們要知道速度這一列的標準差:
1cars1 %>%
2 summarise(speed_sd = sd(speed))
3## # A tibble: 1 x 1
4## speed_sd
5## <dbl>
6## 1 5.29
與求均值的例子相比較,我們知識改變了最後的列名稱speed_sd,以及求值函數sd。我們會通過變化求值函數來進行不同的匯總,首先給大家介紹不同的匯總求值函數。
中心化匯總:平均值(mean)、中位數(median)
離散化匯總:標準差(sd)、四分位距(IQR)、絕對中位差(mad)
範圍匯總:最大值(max)、最小值(min)、分位數(quantile)
位置匯總:首位(first)、末位(last)、自定義位置(nth)
計數匯總:簡單計數(n)、種類計數(n_distinct)
邏輯匯總:最少滿足(any)、全部滿足(all)
上一節中我們介紹的匯總函數已經能夠滿足較為豐富的匯總功能,本節會為每個匯總給出範例,並對一些無法「見名知意」的函數進行具體的介紹。這裡我們會統一對cars1的speed列進行操作。
1#均值
2cars1 %>%
3 summarise(speed.avg = mean(speed))
4## # A tibble: 1 x 1
5## speed.avg
6## <dbl>
7## 1 15.4
8#中位數
9cars1 %>%
10 summarise(speed.median = median(speed))
11## # A tibble: 1 x 1
12## speed.median
13## <dbl>
14## 1 15
需要注意的是,R語言對缺失值是非常敏感的,也就說如果數據中有缺失值,那麼匯總返回的平均值也會是缺失值。如果需要忽略缺失值,應該在mean函數中設置na.rm = T,也就是用以下語句:cars %>% summarise(speed.avg = mean(speed,na.rm = T)).
SQL代碼:
<SQL> SELECT AVG(`speed`) AS `speed.avg`
FROM `cars1`
<SQL> SELECT MEDIAN(`speed`) AS `speed.median`
1#標準差
2cars1 %>%
3 summarise(speed.sd = sd(speed))
4## # A tibble: 1 x 1
5## speed.sd
6## <dbl>
7## 1 5.29
8#IQR
9cars1 %>%
10 summarise(speed.IQR = IQR(speed))
11## # A tibble: 1 x 1
12## speed.IQR
13## <dbl>
14## 1 7
15#MAD
16cars1 %>%
17 summarise(speed.MAD = mad(speed))
18## # A tibble: 1 x 1
19## speed.MAD
20## <dbl>
21## 1 5.93
IQR,四分位距,具體計算方法為IQR(x)= quantile(x, 3/4) - quantile(x, 1/4),也就是處於四分之三位置的數值減去處於四分之一位置的數值的差值。MAD,絕對中位差,指的是所有數值減去中位數的絕對值,然後相加的結果。
SQL代碼如下:
<SQL> SELECT STDEV(`speed`) AS `speed.sd`
FROM `cars1`
<SQL> SELECT IQR(`speed`) AS `speed.IQR`
FROM `cars1`
<SQL> SELECT MAD(`speed`) AS `speed.MAD`
FROM `cars1`
1#最大值
2cars1 %>%
3 summarise(speed.max = max(speed))
4## # A tibble: 1 x 1
5## speed.max
6## <dbl>
7## 1 25
8#最小值
9cars1 %>%
10 summarise(speed.min = min(speed))
11## # A tibble: 1 x 1
12## speed.min
13## <dbl>
14## 1 4
15#50%分位數
16cars1 %>%
17 summarise(speed.quantile = quantile(speed,0.5))
18## # A tibble: 1 x 1
19## speed.quantile
20## <dbl>
21## 1 15
注意分位數需要設定一個唯一值,對於匯總功能而言,一列只能匯總為一個值而不是多個值。另外,這裡設置為0.5,那麼就會求50%分位數,這個用戶可以自定義選擇。
SQL代碼:
<SQL> SELECT MAX(`speed`) AS `speed.max`
FROM `cars1`
<SQL> SELECT MIN(`speed`) AS `speed.min`
FROM `cars1`
<SQL> SELECT QUANTILE(`speed`, 0.5) AS `speed.quantile`
FROM `cars1`
1#首行
2cars1 %>%
3 summarise(speed.1st = first(speed))
4## # A tibble: 1 x 1
5## speed.1st
6## <dbl>
7## 1 4
8#末行
9cars1 %>%
10 summarise(speed.last = last(speed))
11## # A tibble: 1 x 1
12## speed.last
13## <dbl>
14## 1 25
15#第3行
16cars1 %>%
17 summarise(speed.nth = nth(speed,3))
18## # A tibble: 1 x 1
19## speed.nth
20## <dbl>
21## 1 7
1#首行
2cars1 %>%
3 summarise(row.number = n())
4## # A tibble: 1 x 1
5## row.number
6## <int>
7## 1 50
8#檢測了多少種速度
9cars1 %>%
10 summarise(speed.n = n_distinct(speed))
11## # A tibble: 1 x 1
12## speed.n
13## <int>
14## 1 19
n()其實就是統計了表格的總行數,裡面不需要放任何東西。但是如果想要知道試驗中一共檢測了多少種速度,那麼就需要用到n_distinct函數,它會統計一共有多少個不同的速度。
SQL代碼:
<SQL> SELECT COUNT() AS `row.number`
FROM `cars1`
<SQL> SELECT COUNT(DISTINCT `speed`) AS `speed.n`
FROM `cars1`
這個匯總方法的本質是,看看向量中是不是有任意一個能夠滿足要求,或者是否能夠全部滿足要求。例如,學校學生身高是不是全部的同學都超過了1米?有沒有任何同學的身高達到了兩米?需要注意的是,這個匯總會返回一個邏輯型結果,也就是TRUE或者FALSE。
下面還是用我們的數據集來舉例:
1#speed至少有一個是大於10的嗎?
2cars1 %>%
3 summarise(any(speed > 10))
4## # A tibble: 1 x 1
5## `any(speed > 10)`
6## <lgl>
7## 1 TRUE
8#speed中全部數值都大於10嗎?
9cars1 %>%
10 summarise(all(speed > 10))
11## # A tibble: 1 x 1
12## `all(speed > 10)`
13## <lgl>
14## 1 FALSE
SQL代碼:
<SQL> SELECT ANY(`speed` > 10.0) AS `any(speed > 10)`
FROM `cars1`
<SQL> SELECT ALL(`speed` > 10.0) AS `all(speed > 10)`
FROM `cars1`
本章介紹了匯總的基本概念,並通過變換求值函數,實現各種不同的匯總操作。但凡是能夠對向量進行計算並返回單一值的函數,都能夠作為匯總的求值函數,我們甚至可以自定義求值函數,這為我們的工作提供了極大的便利。
往期精彩:
公眾號後臺回復關鍵字即可學習
回復 爬蟲 爬蟲三大案例實戰
回復 Python 1小時破冰入門
回復 數據挖掘 R語言入門及數據挖掘
回復 人工智慧 三個月入門人工智慧
回復 數據分析師 數據分析師成長之路
回復 機器學習 機器學習的商業應用
回復 數據科學 數據科學實戰
回復 常用算法 常用數據挖掘算法