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

2021-02-13 表哥有話講

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

郵箱:huang.tian-yuan@qq.com

前言

本章節介紹如何根據條件對表格進行過濾,主要使用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##    <chr>   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
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 <dbl>

實際工作中,經常會需要用到把一定條件的記錄調出來的情況。比如,如果我是超市的數據分析師,我需要查看單次消費超過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##    <chr>   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
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 <dbl>

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

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

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

下面我們再舉一個實際例子,比如我們需要除了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##    <chr>   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
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 <dbl>

SQL代碼如下:

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

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

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

1df <- tibble(x = c(1, 2, NA), y = c("a", NA, "b"))
2df #原始數據框
3## # A tibble: 3 x 2
4##       x y    
5##   <dbl> <chr>
6## 1     1 a    
7## 2     2 <NA> 
8## 3    NA b
9df %>% drop_na()   #去掉含有缺失值的行
10## # A tibble: 1 x 2
11##       x y    
12##   <dbl> <chr>
13## 1     1 a
14df %>% drop_na(x)  #去掉x列含有缺失值的行
15## # A tibble: 2 x 2
16##       x y    
17##   <dbl> <chr>
18## 1     1 a    
19## 2     2 <NA>

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

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

SQL代碼如下:

1<SQL> 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##   <chr>  <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
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##   <chr>  <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
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<SQL> 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##    <chr>   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
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 <dbl>

SQL代碼如下:

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

1mtcars1 %>%
2  filter(!cyl == 4)
3## # A tibble: 21 x 12
4##    rowname   mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear
5##    <chr>   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
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 <dbl>
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##    <chr>   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
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 <dbl>

SQL代碼如下:

1<SQL> 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##   <chr>  <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
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<SQL> SELECT *
2FROM `mtcars1`
3WHERE (INSTR(

我們看到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##    <chr>   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
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 <dbl>

SQL代碼為:

1<SQL> SELECT *
2FROM `mtcars1`
3WHERE (INSTR(

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

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


往期精彩:


公眾號後臺回復關鍵字即可學習

回復 爬蟲            爬蟲三大案例實戰
回復 Python       1小時破冰入門
回復 數據挖掘     R語言入門及數據挖掘
回復 人工智慧     三個月入門人工智慧
回復 數據分析師  數據分析師成長之路 
回復 機器學習     機器學習的商業應用
回復 數據科學     數據科學實戰
回復 常用算法     常用數據挖掘算法

相關焦點

  • 案例詳解:filter 過濾、map 映射、reduce累積
    filter()函數用於過濾序列。
  • 每日單詞129---​Filter
    Filter[ˈfɪltə(r)]n.濾波器; 濾光器; 濾色鏡; [化] 過濾器
  • jQuery的first()、last()、eq()、filter()和not()方法過濾元素
    01第1節:jQuery過濾概述在jQuery中,針對Html元素封裝了一系列的遍歷方法,有遍歷祖先的parent()/parents(),還有遍歷子孫的children()/find(),也有遍歷同胞的siblings()/next()/prev()
  • 一日一技:在Python中使用過濾函數filter
    可能有一些人會使用列表推導式:a = [1, 2, False, '', 'test', 0]useful = [x for x in a if x]但如果過濾規則稍微複雜一些呢?例如,如果列表裡面的元素不是字符串,那麼先把元素轉換為字符串,然後轉換為bytes型數據,計算md5值。
  • 【數組分享】PHP函數array_filter ()分享(2020-10-31)
    array_filter () 用回調函數過濾數組中的單元。 array array_filter ( array $array [, callable $callback [, int $flag = 0 ]] )依次將 array 數組中的每個值傳遞到 callback 函數。
  • R中過濾低豐度物種的幾種方式
    過濾在所有樣本中相對豐度小於1%的物種gene_filter <-data.frame(gene_precent1[apply(gene_precent1,1,max)>0.01,])2.,也就是H組gene_precent1$Hmean <- apply(gene_precent1[,7:12],1,mean)# 過濾gene_filter <- subset(gene_precent1,Dmean > 0.01|Hmean>0.01) %>%  select(.
  • R語言ETL系列:匯總(summarise)
    希望與大家分享學習經驗,推廣並加深R語言在業界的應用。郵箱:huang.tian-yuan@qq.com本章講解如何使用summarise函數完成數據的匯總。在開講之前,我們需要理解,什麼叫做匯總。舉個例子,如果我們現在對學校的學生身高進行了測量,我們需要得到學生的平均身高,那麼我們把所有學生的身高加起來,除以學生的數量,得到身高平均值,這就完成了一個匯總計算。
  • R語言學習指南(3) tidyverse的基礎使用
    tidyverse是為數據科學設計的R軟體包,它包含(ggplot2、dplyr、tidyr、stringr、magrittr、tibble)等一系列熱門軟體包,學好tidyverse的使用可也讓你站上另一個高度,從而高效的處理數據,因此本文檔不僅僅做一些案例介紹,而是希望以較為正確的學習方法來介紹R語言,使大家少走彎路,快速入門掌握R語言
  • R語言 | 數據操作dplyr包
    [更新~] Python網絡爬蟲與文本數據分析公眾號只帶著Python字眼,卻分享著R語言,不務正業,任性了~dplyr簡介dplyr是R語言的數據分析包,很像python中的pandas,能對dataframe
  • vcf文件的過濾-vcftools
    好像最近大家都在做過濾,藉此整理一下plink對文件格式敏感,更容易報錯,所以我先使用vcftools過濾,後續的LD過濾
  • R語言數據清洗實戰——高效list解析方案
    杜雨:EasyCharts團隊成員,R語言中文社區專欄作者。興趣方向為:Excel商務圖表,R語言數據可視化,地理信息數據可視化。個人公眾號:數據小魔方(微信ID:datamofang) ,「數據小魔方」創始人。
  • R語言完美重現STAMP結果圖
    寫在前面之前寫過一篇關於統計學軟體STAMP的教程,使用STAMP對微生物群落數據進行統計學分析還是挺方便的,尤其是對R
  • 自定義生成器函數模擬Python內置函數filter()
    ==================作為Python函數式編程的三大巨頭之一,內置函數filter()的地位是非常重要的,其語法為:filter(function or None, iterable) --> filter objectfilter()函數使用指定函數描述的規則對序列中的元素進行過濾,返回包含符合規則的元素的filter
  • 如何使用Python的filter函數
    filter()函數所提供的過濾方法,通常比用列表解析更有效,特別是當我們處理更大的數據集時。例如,列表解析會生成一個新列表,這會增加該處理的運行時間。當列表解析執行完畢它的表達式後,內存中會有兩個列表。但是,filter()將生成一個簡單的對象,該對象包含對原始列表的引用、提供的函數以及原始列表中位置的索引,這樣操作佔用的內存更少。
  • R語言ETL系列:創建欄位(mutate)
    希望與大家分享學習經驗,推廣並加深R語言在業界的應用。郵箱:huang.tian-yuan@qq.com有沒有一些時候你想要給表格加一個新的列?本章將會介紹如何在表格中創建新的欄位。>往期精彩:公眾號後臺回復關鍵字即可學習回復 爬蟲            爬蟲三大案例實戰回復 Python       1小時破冰入門回復 數據挖掘     R語言入門及數據挖掘
  • R語言ETL工程系列:排序(arrange)
    希望與大家分享學習經驗,推廣並加深R語言在業界的應用。郵箱:huang.tian-yuan@qq.com前言上篇介紹如何從表中檢索一個或多個數據列,本章介紹如何在R中對表格數據進行排序,主要使用arrange函數。
  • 實例中學習python的walk/map/filter/lambda
    背景程式語言只有在實際使用中才能積累實戰經驗,才能真正掌握。
  • reduce()函數和filter()函數閃亮登場
    二.filter()函數  filter()函數是Python中常見的一個內置函數。filter()函數用於過濾掉序列中不符合條件的元素,返回由符合條件的元素組成的新序列。  filter()函數的語法是:filter(function or None, iterable)  其中function是過濾函數,iterable為一個過濾序列或可迭代對象。
  • javaweb學習之過濾器(Filter)的使用
    並且一個請求或一個響應都可以經過多層過濾器,如下圖所示:用途自動登錄設置統一的編碼格式,避免亂碼訪問權限的控制進行敏感字符過濾(如經常遇到的不文明發言被過濾或者以「*」的形式顯示出來)......示例這裡以一個servlet和一個filter作為示例。
  • R語言 | Tidyverse包入門介紹
    Analyzing Linguistic DataR Graphics Cookbook··· ···R: The R Project for Statistical Computinghttps://www.r-project.org