R語言ETL系列:過濾(filter)


R語言ETL系列:過濾(filter)

歡迎關注天善智能,我們是專注於商業智能BI,人工智能AI,大數據分析與挖掘領域的垂直社區,學習,問答、求職一站式搞定!

對商業智能BI、大數據分析挖掘、機器學習,python,R等數據領域感興趣的同學加微信:tstoutiao,邀請你進入數據愛好者交流群,數據愛好者們都在這兒。

作者:黃天元,復旦大學博士在讀,目前研究涉及文本挖掘、社交網絡分析和機器學習等。希望與大家分享學習經驗,推廣並加深R語言在業界的應用。

郵箱:[email protected]

前言

本章節介紹如何根據條件對錶格進行過濾,主要使用filter函數進行實現。

首先加載需要的包和數據,我們會用到R語言自帶的mtcars數據集。首先我們把行的名稱轉化為一列數據,名為rownams。然後,把數據庫轉化為tibble格式,存在mtcars1變量中。


 1library(tidyverse)
2
3mtcars %>%
4 rownames_to_column() %>%
5 as_tibble() -> mtcars1
6
7mtcars1
8## # A tibble: 32 x 12
9## rowname mpg cyl disp hp drat wt qsec vs am gear
10##
11## 1 Mazda ~ 21 6 160 110 3.9 2.62 16.5 0 1 4
12## 2 Mazda ~ 21 6 160 110 3.9 2.88 17.0 0 1 4
13## 3 Datsun~ 22.8 4 108 93 3.85 2.32 18.6 1 1 4
14## 4 Hornet~ 21.4 6 258 110 3.08 3.22 19.4 1 0 3
15## 5 Hornet~ 18.7 8 360 175 3.15 3.44 17.0 0 0 3
16## 6 Valiant 18.1 6 225 105 2.76 3.46 20.2 1 0 3
17## 7 Duster~ 14.3 8 360 245 3.21 3.57 15.8 0 0 3
18## 8 Merc 2~ 24.4 4 147. 62 3.69 3.19 20 1 0 4
19## 9 Merc 2~ 22.8 4 141. 95 3.92 3.15 22.9 1 0 4
20## 10 Merc 2~ 19.2 6 168. 123 3.92 3.44 18.3 1 0 4
21## # ... with 22 more rows, and 1 more variable: carb


條件過濾:filter

實際工作中,經常會需要用到把一定條件的記錄調出來的情況。比如,如果我是超市的數據分析師,我需要查看單次消費超過500元的購物清單,就需要用到條件過濾。在我們的例子中,比如我們需要提取cyl為4的記錄(cyl代表汽車氣缸的數量),就可以這麼操作:

 1mtcars1 %>%
2 filter(cyl == 4)
3## # A tibble: 11 x 12
4## rowname mpg cyl disp hp drat wt qsec vs am gear
5##
6## 1 Datsun~ 22.8 4 108 93 3.85 2.32 18.6 1 1 4
7## 2 Merc 2~ 24.4 4 147. 62 3.69 3.19 20 1 0 4
8## 3 Merc 2~ 22.8 4 141. 95 3.92 3.15 22.9 1 0 4
9## 4 Fiat 1~ 32.4 4 78.7 66 4.08 2.2 19.5 1 1 4
10## 5 Honda ~ 30.4 4 75.7 52 4.93 1.62 18.5 1 1 4
11## 6 Toyota~ 33.9 4 71.1 65 4.22 1.84 19.9 1 1 4
12## 7 Toyota~ 21.5 4 120. 97 3.7 2.46 20.0 1 0 3
13## 8 Fiat X~ 27.3 4 79 66 4.08 1.94 18.9 1 1 4
14## 9 Porsch~ 26 4 120. 91 4.43 2.14 16.7 0 1 5
15## 10 Lotus ~ 30.4 4 95.1 113 3.77 1.51 16.9 1 1 5
16## 11 Volvo ~ 21.4 4 121 109 4.11 2.78 18.6 1 1 4
17## # ... with 1 more variable: carb

結果中我們可以看到,氣缸數量為4的記錄都被我們調出來了。相關SQL代碼如下

1 SELECT *
2FROM `mtcars1`
3WHERE (`cyl` = 4.0)


如何定義條件

什麼是條件?很簡單,是或不是。比如上面的例子,如果cyl等於4,就符合條件,否則不符合條件。因此只要我們的語句能夠返回一個邏輯值(也就是計算機能夠讀懂的TURE或者FALSE),那麼就能夠構成一個條件。基本的條件操作符如下所示:


R語言ETL系列:過濾(filter)


下面我們再舉一個實際例子,比如我們需要除了4個氣缸以外的數據,可以這麼寫:

 1mtcars1 %>%
2 filter(cyl != 4)
3## # A tibble: 21 x 12
4## rowname mpg cyl disp hp drat wt qsec vs am gear
5##
6## 1 Mazda ~ 21 6 160 110 3.9 2.62 16.5 0 1 4
7## 2 Mazda ~ 21 6 160 110 3.9 2.88 17.0 0 1 4
8## 3 Hornet~ 21.4 6 258 110 3.08 3.22 19.4 1 0 3
9## 4 Hornet~ 18.7 8 360 175 3.15 3.44 17.0 0 0 3
10## 5 Valiant 18.1 6 225 105 2.76 3.46 20.2 1 0 3
11## 6 Duster~ 14.3 8 360 245 3.21 3.57 15.8 0 0 3
12## 7 Merc 2~ 19.2 6 168. 123 3.92 3.44 18.3 1 0 4
13## 8 Merc 2~ 17.8 6 168. 123 3.92 3.44 18.9 1 0 4
14## 9 Merc 4~ 16.4 8 276. 180 3.07 4.07 17.4 0 0 3
15## 10 Merc 4~ 17.3 8 276. 180 3.07 3.73 17.6 0 0 3
16## # ... with 11 more rows, and 1 more variable: carb

SQL代碼如下:

1 SELECT *
2FROM `mtcars1`
3WHERE (`cyl` != 4.0)


過濾缺失值

現實生產或商務活動中,總會有一些數據採集不到,這時候就會出現缺失值。作分析的時候,如果有缺失值,就無法進行正確計算,比如計算均值的時候,就不容許數據中包含缺失值。如何去除掉缺失值呢?這裡我們可以使用drop_na函數。

下面我們先構造一個3*2的數據框,並在裡面設置缺失值。例子如下:

 1df  2df #原始數據框
3## # A tibble: 3 x 2
4## x y
5##
6## 1 1 a
7## 2 2
8## 3 NA b
9df %>% drop_na() #去掉含有缺失值的行

10## # A tibble: 1 x 2
11## x y
12##
13## 1 1 a
14df %>% drop_na(x) #去掉x列含有缺失值的行
15## # A tibble: 2 x 2
16## x y
17##
18## 1 1 a
19## 2 2

我們可以看到,使用drop_na函數,我們可以輕鬆地去掉包含缺失值的行,而且還可以指定去除某列中含有缺失值的行。那麼,我們怎麼找到這些具有缺失值的行呢?非常簡單,利用is.na函數即可,例子如下:

1df %>%
2 filter(is.na(x))
3## # A tibble: 1 x 2
4## x y
5##
6## 1 NA b

SQL代碼

如下:

1 SELECT *
2FROM `df`
3WHERE (((`x`) IS NULL))


組合過濾

如果只有一個條件,也許非常簡單。但是條件很多的時候,我們就需要使用邏輯操作符來把條件組合起來,一起進行過濾。經典的邏輯操作符包括&(與)、|(或)、!(非),有的編程語言會用英語AND/OR/NOT來表示這些邏輯關係,但是在邏輯層面上表達是一致的。下面通過一個例子來說明這些邏輯關係:

  • &:如果顧客最近一週買了東西且(&)買的東西超過100元,那麼我們把這些顧客的交易記錄調出來;
  • |:如果顧客最近一週買了東西或者(|)購買東西的頻率維持在一週一次,那麼我們把這些顧客的交易記錄調出來;
  • !:我們只考慮女性客戶,因此男性客戶都剔除(!)掉。


&

操作符

我們想要篩選氣缸(cyl)為4,而且馬力(hp)大於100的汽車。

 1mtcars1 %>%
2 filter(cyl == 4 & hp > 100)
3## # A tibble: 2 x 12
4## rowna~ mpg cyl disp hp drat wt qsec vs am gear carb
5##
6## 1 Lotus~ 30.4 4 95.1 113 3.77 1.51 16.9 1 1 5 2
7## 2 Volvo~ 21.4 4 121 109 4.11 2.78 18.6 1 1 4 2
8#等價於
9mtcars1 %>%
10 filter(cyl == 4,hp > 100)
11## # A tibble: 2 x 12
12## rowna~ mpg cyl disp hp drat wt qsec vs am gear carb
13##

14## 1 Lotus~ 30.4 4 95.1 113 3.77 1.51 16.9 1 1 5 2
15## 2 Volvo~ 21.4 4 121 109 4.11 2.78 18.6 1 1 4 2

SQL代碼如下:

1 SELECT *
2FROM `mtcars1`
3WHERE ((`cyl` = 4.0) AND (`hp` > 100.0))

|

操作符

我們想要篩選氣缸(cyl)為4,或者馬力(hp)大於100的汽車。

 1mtcars1 %>%
2 filter(cyl == 4 | hp > 100)

3## # A tibble: 32 x 12
4## rowname mpg cyl disp hp drat wt qsec vs am gear
5##
6## 1 Mazda ~ 21 6 160 110 3.9 2.62 16.5 0 1 4
7## 2 Mazda ~ 21 6 160 110 3.9 2.88 17.0 0 1 4
8## 3 Datsun~ 22.8 4 108 93 3.85 2.32 18.6 1 1 4
9## 4 Hornet~ 21.4 6 258 110 3.08 3.22 19.4 1 0 3
10## 5 Hornet~ 18.7 8 360 175 3.15 3.44 17.0 0 0 3
11## 6 Valiant 18.1 6 225 105 2.76 3.46 20.2 1 0 3
12## 7 Duster~ 14.3 8 360 245 3.21 3.57 15.8 0 0 3
13## 8 Merc 2~ 24.4 4 147. 62 3.69 3.19 20 1 0 4
14## 9 Merc 2~ 22.8 4 141. 95 3.92 3.15 22.9 1 0 4
15## 10 Merc 2~ 19.2 6 168. 123 3.92 3.44 18.3 1 0 4
16## # ... with 22 more rows, and 1 more variable: carb

SQL代碼如下:

1 SELECT *
2FROM `mtcars1`
3WHERE (`cyl` = 4.0 OR `hp` > 100.0)

!

操作符

我們想要篩選除了4個氣缸以外的汽車記錄。

 1mtcars1 %>%
2 filter(!cyl == 4)
3## # A tibble: 21 x 12
4## rowname mpg cyl disp hp drat wt qsec vs am gear
5##
6## 1 Mazda ~ 21 6 160 110 3.9 2.62 16.5 0 1 4
7## 2 Mazda ~ 21 6 160 110 3.9 2.88 17.0 0 1 4
8## 3 Hornet~ 21.4 6 258 110 3.08 3.22 19.4 1 0 3
9## 4 Hornet~ 18.7 8 360 175 3.15 3.44 17.0 0 0 3
10## 5 Valiant 18.1 6 225 105 2.76 3.46 20.2 1 0 3
11## 6 Duster~ 14.3 8 360 245 3.21 3.57 15.8 0 0 3
12## 7 Merc 2~ 19.2 6 168. 123 3.92 3.44 18.3 1 0 4
13## 8 Merc 2~ 17.8 6 168. 123 3.92 3.44 18.9 1 0 4
14## 9 Merc 4~ 16.4 8 276. 180 3.07 4.07 17.4 0 0 3
15## 10 Merc 4~ 17.3 8 276. 180 3.07 3.73 17.6 0 0 3
16## # ... with 11 more rows, and 1 more variable: carb
17#等價於
18mtcars1 %>%
19 filter(cyl != 4)
20## # A tibble: 21 x 12
21## rowname mpg cyl disp hp drat wt qsec vs am gear
22##

23## 1 Mazda ~ 21 6 160 110 3.9 2.62 16.5 0 1 4
24## 2 Mazda ~ 21 6 160 110 3.9 2.88 17.0 0 1 4
25## 3 Hornet~ 21.4 6 258 110 3.08 3.22 19.4 1 0 3
26## 4 Hornet~ 18.7 8 360 175 3.15 3.44 17.0 0 0 3
27## 5 Valiant 18.1 6 225 105 2.76 3.46 20.2 1 0 3
28## 6 Duster~ 14.3 8 360 245 3.21 3.57 15.8 0 0 3
29## 7 Merc 2~ 19.2 6 168. 123 3.92 3.44 18.3 1 0 4
30## 8 Merc 2~ 17.8 6 168. 123 3.92 3.44 18.9 1 0 4
31## 9 Merc 4~ 16.4 8 276. 180 3.07 4.07 17.4 0 0 3
32## 10 Merc 4~ 17.3 8 276. 180 3.07 3.73 17.6 0 0 3
33## # ... with 11 more rows, and 1 more variable: carb

SQL代碼如下:

1 SELECT *
2FROM `mtcars1`
3WHERE (NOT(`cyl` = 4.0))

文本過濾

數據表中的數據不都是數值型的,有的是字符串格式存在的文本。在我們的例子中,比如我們想了解Merc這個型號的車,那麼我們就要從rowname列中個提取包含“Merc”的行。

R語言tidyverse包中,包含了stringr包,可以對字符串進行識別、替換、提取等高級操作。如果我們要根據字符串進行過濾,就需要用到str_detect函數,例子如下:

 1#提取rowname中包含“Merc”的記錄
2
3mtcars1 %>%
4 filter(str_detect(rowname,pattern = "Merc"))
5## # A tibble: 7 x 12
6## rowna~ mpg cyl disp hp drat wt qsec vs am gear carb
7##
8## 1 Merc ~ 24.4 4 147. 62 3.69 3.19 20 1 0 4 2
9## 2 Merc ~ 22.8 4 141. 95 3.92 3.15 22.9 1 0 4 2
10## 3 Merc ~ 19.2 6 168. 123 3.92 3.44 18.3 1 0 4 4
11## 4 Merc ~ 17.8 6 168. 123 3.92 3.44 18.9 1 0 4 4
12## 5 Merc ~ 16.4 8 276. 180 3.07 4.07 17.4 0 0 3 3
13## 6 Merc ~ 17.3 8 276. 180 3.07 3.73 17.6 0 0 3 3

14## 7 Merc ~ 15.2 8 276. 180 3.07 3.78 18 0 0 3 3

SQL代碼為:

1 SELECT *
2FROM `mtcars1`
3WHERE (INSTR('^Merc', `rowname`) > 0)

我們看到pattern參數中,我們賦予了“Merc”模式。事實上,pattern可以接受正則表達式的內容,比如我們要搜索以M開頭的車型,那麼就可以把pattern改為“^M”:

 1mtcars1 %>%
2 filter(str_detect(rowname,pattern = "^M"))
3## # A tibble: 10 x 12
4## rowname mpg cyl disp hp drat wt qsec vs am gear
5##

6## 1 Mazda ~ 21 6 160 110 3.9 2.62 16.5 0 1 4
7## 2 Mazda ~ 21 6 160 110 3.9 2.88 17.0 0 1 4
8## 3 Merc 2~ 24.4 4 147. 62 3.69 3.19 20 1 0 4
9## 4 Merc 2~ 22.8 4 141. 95 3.92 3.15 22.9 1 0 4
10## 5 Merc 2~ 19.2 6 168. 123 3.92 3.44 18.3 1 0 4
11## 6 Merc 2~ 17.8 6 168. 123 3.92 3.44 18.9 1 0 4
12## 7 Merc 4~ 16.4 8 276. 180 3.07 4.07 17.4 0 0 3
13## 8 Merc 4~ 17.3 8 276. 180 3.07 3.73 17.6 0 0 3
14## 9 Merc 4~ 15.2 8 276. 180 3.07 3.78 18 0 0 3
15## 10 Masera~ 15 8 301 335 3.54 3.57 14.6 0 1 5
16## # ... with 1 more variable: carb

SQL代碼為:

1 SELECT *
2FROM `mtcars1`
3WHERE (INSTR('^M', `rowname`) > 0)

正則表達式是一個很有用的工具,如果能夠寫出高效的正則表達式,就能夠對字符串進行更加高級的篩選。不過正則表達式超出了本系列的範圍,因此不進行更多的介紹。

本章介紹瞭如何用filter函數完成過濾,我們瞭解瞭如何通過構造條件來對數據表的記錄進行篩選。此外,我們能夠去掉表格中含有缺失值的數據,還能把這些缺失的記錄單獨提取出來。最後,我們學會了如何通過構造組合過濾來進行復雜的表格數據篩選,並知道如何利用str_detect函數對文本格式的數據進行篩選。


R語言ETL系列:過濾(filter)


往期精彩:

R語言ETL系列:過濾(filter)

回覆 爬蟲 爬蟲三大案例實戰

回覆 Python 1小時破冰入門

回覆 數據挖掘 R語言入門及數據挖掘

回覆 人工智能 三個月入門人工智能

回覆 數據分析師 數據分析師成長之路

回覆 機器學習 機器學習的商業應用

回覆 數據科學 數據科學實戰

回覆 常用算法 常用數據挖掘算法


分享到:


相關文章: