R语言ETL系列:过滤(filter)

栏目: R语言 · 发布时间: 5年前

R语言ETL系列:过滤(filter)

作者: 黄天元 ,复旦大学博士在读,目前研究涉及文本挖掘、社交网络分析和机器学习等。希望与大家分享学习经验,推广并加深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> 

条件过滤: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##    <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),那么就能够构成一个条件。基本的条件操作符如下所示:

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##    <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) 

!

操作符

我们想要筛选除了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> 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('^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##    <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('^M', `rowname`) > 0) 

正则表达式是一个很有用的工具,如果能够写出高效的正则表达式,就能够对字符串进行更加高级的筛选。不过正则表达式超出了本系列的范围,因此不进行更多的介绍。

本章介绍了如何用filter函数完成过滤,我们了解了如何通过构造条件来对数据表的记录进行筛选。此外,我们能够去掉表格中含有缺失值的数据,还能把这些缺失的记录单独提取出来。最后,我们学会了如何通过构造组合过滤来进行复杂的表格数据筛选,并知道如何利用str_detect函数对文本格式的数据进行筛选。

往期精彩:

R语言ETL系列:过滤(filter)

公众号后台回复关键字即可学习

回复  爬虫             爬虫三大案例实战

回复  Python        1小时破冰入门

回复  数据挖掘      R语言入门及数据挖掘

回复  人工智能      三个月入门人工智能

回复  数据分析师   数据分析师成长之路 

回复  机器学习      机器学习的商业应用

回复  数据科学      数据科学实战

回复  常用算法     

常用数据挖掘算法

本文由R语言中文社区 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。

转载、引用前需联系作者,并署名作者且注明文章出处。

本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

首席产品官1 从新手到行家

首席产品官1 从新手到行家

车马 / 机械工业出版社 / 2018-9-25 / 79

《首席产品官》共2册,旨在为产品新人成长为产品行家,产品白领成长为产品金领,最后成长为首席产品官(CPO)提供产品认知、能力体系、成长方法三个维度的全方位指导。 作者在互联网领域从业近20年,是中国早期的互联网产品经理,曾是周鸿祎旗下“3721”的产品经理,担任CPO和CEO多年。作者将自己多年来的产品经验体系化,锤炼出了“产品人的能力杠铃模型”(简称“杠铃模型”),简洁、直观、兼容性好、实......一起来看看 《首席产品官1 从新手到行家》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

SHA 加密
SHA 加密

SHA 加密工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具