数据处理第3部分:选择行的基本和高级的方法

简介: 原文地址:https://suzan.rbind.io/2018/02/dplyr-tutorial-3/作者:Suzan Baert这是系列dplyr系列教程中的第三篇博客文章。

原文地址:https://suzan.rbind.io/2018/02/dplyr-tutorial-3/
作者:Suzan Baert
这是系列dplyr系列教程中的第三篇博客文章。 在这篇文章中,我们将介绍如何挑选您的数据。 除了filter的基础知识外,它还介绍了一些更好的方法,用near()between()挑选数字列,或用正则表达式过滤字符串列。


The data
根据之前的博客文章,为了方便人们复制粘贴代码和实验,我使用的是内置数据集。 此数据集内置于ggplot2中,因此如果您加载tidyverse,您将获得它。 否则,只需添加一次msleep < - ggplot2 :: msleep参数即可获得数据集。

library(dplyr)
library(stringr)
msleep <- ggplot2::msleep

glimpse(msleep)

## Observations: 83
## Variables: 11
## $ name         <chr> "Cheetah", "Owl monkey", "Mountain beaver", "Grea...
## $ genus        <chr> "Acinonyx", "Aotus", "Aplodontia", "Blarina", "Bo...
## $ vore         <chr> "carni", "omni", "herbi", "omni", "herbi", "herbi...
## $ order        <chr> "Carnivora", "Primates", "Rodentia", "Soricomorph...
## $ conservation <chr> "lc", NA, "nt", "lc", "domesticated", NA, "vu", N...
## $ sleep_total  <dbl> 12.1, 17.0, 14.4, 14.9, 4.0, 14.4, 8.7, 7.0, 10.1...
## $ sleep_rem    <dbl> NA, 1.8, 2.4, 2.3, 0.7, 2.2, 1.4, NA, 2.9, NA, 0....
## $ sleep_cycle  <dbl> NA, NA, NA, 0.1333333, 0.6666667, 0.7666667, 0.38...
## $ awake        <dbl> 11.9, 7.0, 9.6, 9.1, 20.0, 9.6, 15.3, 17.0, 13.9,...
## $ brainwt      <dbl> NA, 0.01550, NA, 0.00029, 0.42300, NA, NA, NA, 0....
## $ bodywt       <dbl> 50.000, 0.480, 1.350, 0.019, 600.000, 3.850, 20.4...

Basic row filters

在许多情况下,您不希望在分析中包括所有行,而只包括选择的行。 仅使用特定行的函数在dplyr中称为“filter()”。 过滤器的一般语法是:filter(dataset,condition)。 如果您在管道内部进行过滤,则只会在数据集通过管道输入函数时看到条件参数。

Filtering rows based on a numeric variable

You can filter numeric variables based on their values. The most used operators for this are >, >=, <, <=, == and !=.

msleep %>% 
  select(name, sleep_total) %>% 
  filter(sleep_total > 18)

## # A tibble: 4 x 2
##   name                 sleep_total
##   <chr>                      <dbl>
## 1 Big brown bat               19.7
## 2 Thick-tailed opposum        19.4
## 3 Little brown bat            19.9
## 4 Giant armadillo             18.1

如果要选择一系列值,可以使用两个逻辑要求。 例如,为了选择总休眠时间在15到18小时之间的所有动物,我可以使用:filter(sleep_total> = 16,sleep_total <= 18),但使用between()稍微短一些

msleep %>% 
  select(name, sleep_total) %>% 
  filter(between(sleep_total, 16, 18))

## # A tibble: 4 x 2
##   name                   sleep_total
##   <chr>                        <dbl>
## 1 Owl monkey                    17.0
## 2 Long-nosed armadillo          17.4
## 3 North American Opossum        18.0
## 4 Arctic ground squirrel        16.6

可以派上用场的另一个函数是near(),它将选择几乎给定值的所有代码。 您必须指定容差“tol”以指示值可以达到多远。 你可以添加一个特定的数字:filter(near(sleep_total,17,tol = 0.5))例如将返回sleep_total在16.5和17.5之间的任何行,或者你可以添加一个公式。
示例代码将返回一个标准差为17的所有行。

msleep %>% 
  select(name, sleep_total) %>% 
  filter(near(sleep_total, 17, tol = sd(sleep_total)))

## # A tibble: 26 x 2
##    name                       sleep_total
##    <chr>                            <dbl>
##  1 Owl monkey                        17.0
##  2 Mountain beaver                   14.4
##  3 Greater short-tailed shrew        14.9
##  4 Three-toed sloth                  14.4
##  5 Long-nosed armadillo              17.4
##  6 North American Opossum            18.0
##  7 Big brown bat                     19.7
##  8 Western american chipmunk         14.9
##  9 Thick-tailed opposum              19.4
## 10 Mongolian gerbil                  14.2
## # ... with 16 more rows

Filtering based on a exact character variable matches

例如,如果要选择特定的动物组,可以使用==比较运算符:

msleep %>% 
  select(order, name, sleep_total) %>% 
  filter(order == "Didelphimorphia")

## # A tibble: 2 x 3
##   order           name                   sleep_total
##   <chr>           <chr>                        <dbl>
## 1 Didelphimorphia North American Opossum        18.0
## 2 Didelphimorphia Thick-tailed opposum          19.4

同样,您可以使用其他运算符:

*filter(order!=“Rodentia”)将选择除Rodentia行之外的所有内容。

*filter(name>“v”)只会在字母v之后选择字母中带有名称的行。

如果要选择多个动物,可以使用%in%运算符。 以下代码将仅选择具有属于Didelphimorphia和Diprotodontia顺序的动物的行。

msleep %>% 
  select(order, name, sleep_total) %>% 
  filter(order %in% c("Didelphimorphia", "Diprotodontia"))

## # A tibble: 4 x 3
##   order           name                   sleep_total
##   <chr>           <chr>                        <dbl>
## 1 Didelphimorphia North American Opossum        18.0
## 2 Didelphimorphia Thick-tailed opposum          19.4
## 3 Diprotodontia   Phalanger                     13.7
## 4 Diprotodontia   Potoroo                       11.1

您可以使用%in%运算符来取消选择某些组,在这种情况下,您必须通过在filter的开头添加感叹号来否定。 制作!%in%似乎是逻辑但它不起作用。

remove <- c("Rodentia", "Carnivora", "Primates")
msleep %>% 
  select(order, name, sleep_total) %>% 
  filter(!order %in% remove)

## # A tibble: 37 x 3
##    order           name                       sleep_total
##    <chr>           <chr>                            <dbl>
##  1 Soricomorpha    Greater short-tailed shrew       14.9 
##  2 Artiodactyla    Cow                               4.00
##  3 Pilosa          Three-toed sloth                 14.4 
##  4 Artiodactyla    Roe deer                          3.00
##  5 Artiodactyla    Goat                              5.30
##  6 Soricomorpha    Star-nosed mole                  10.3 
##  7 Soricomorpha    Lesser short-tailed shrew         9.10
##  8 Cingulata       Long-nosed armadillo             17.4 
##  9 Hyracoidea      Tree hyrax                        5.30
## 10 Didelphimorphia North American Opossum           18.0 
## # ... with 27 more rows

根据正则表达式过滤行

只有在您可以使用完整变量内容时,上述选项才有效。 在某些情况下,虽然需要根据部分匹配进行过滤。 在这种情况下,我们需要一个函数来评估字符串上的正则表达式并返回布尔值。 每当语句为“TRUE”时,该行将被过滤。
这有两个主要选项:base R的grepl()函数,或stringr包中的str_detect()

无论何时寻找部分匹配,重要的是要记住R是区分大小写的。 通过使用filter(str_detect(name,pattern =“mouse”))我们将遗漏任何名为Mouse的行。 在这种情况下,它没有什么区别,但它是一个很好的习惯创建。

我在下面使用了'str_detect(),因为它更容易理解。 对于那些感兴趣的人,替代方案是:filter(grepl(pattern =“mouse”,tolower(name)))`。

msleep %>% 
  select(name, sleep_total) %>% 
  filter(str_detect(tolower(name), pattern = "mouse"))

## # A tibble: 5 x 2
##   name                       sleep_total
##   <chr>                            <dbl>
## 1 Vesper mouse                      7.00
## 2 House mouse                      12.5 
## 3 Northern grasshopper mouse       14.5 
## 4 Deer mouse                       11.5 
## 5 African striped mouse             8.70

基于多种条件的过滤

以上示例基于单个条件返回行,但filter选项还允许AND和OR样式过滤器:

*filter(condition1,condition2)将返回满足两个条件的行。

*filter(condition1,!condition2)将返回条件1为真但条件2不为的所有行。

*filter(condition1 | condition2)将返回满足条件1和/或条件2的行。

*filter(xor(condition1,condition2)将返回只满足其中一个条件的所有行,而不是满足两个条件时。

可以组合多个AND,OR和NOT条件。 示例代码将返回bodywt大于100的所有行,并且sleep_total大于15或者不是Carnivora订单的一部分。

msleep %>% 
  select(name, order, sleep_total:bodywt) %>% 
  filter(bodywt > 100, (sleep_total > 15 | order != "Carnivora"))

## # A tibble: 10 x 8
##    name      order  sleep_total sleep_rem sleep_cycle awake brainwt bodywt
##    <chr>     <chr>        <dbl>     <dbl>       <dbl> <dbl>   <dbl>  <dbl>
##  1 Cow       Artio~        4.00     0.700       0.667 20.0    0.423    600
##  2 Asian el~ Probo~        3.90    NA          NA     20.1    4.60    2547
##  3 Horse     Peris~        2.90     0.600       1.00  21.1    0.655    521
##  4 Donkey    Peris~        3.10     0.400      NA     20.9    0.419    187
##  5 Giraffe   Artio~        1.90     0.400      NA     22.1   NA        900
##  6 Pilot wh~ Cetac~        2.70     0.100      NA     21.4   NA        800
##  7 African ~ Probo~        3.30    NA          NA     20.7    5.71    6654
##  8 Tiger     Carni~       15.8     NA          NA      8.20  NA        163
##  9 Brazilia~ Peris~        4.40     1.00        0.900 19.6    0.169    208
## 10 Bottle-n~ Cetac~        5.20    NA          NA     18.8   NA        173

Example with xor()

msleep %>%
  select(name, bodywt:brainwt) %>% 
  filter(xor(bodywt > 100, brainwt > 1))

## # A tibble: 5 x 3
##   name            bodywt brainwt
##   <chr>            <dbl>   <dbl>
## 1 Cow              600     0.423
## 2 Horse            521     0.655
## 3 Donkey           187     0.419
## 4 Human             62.0   1.32 
## 5 Brazilian tapir  208     0.169

Example with !:
The sample code will select all rows where brainwt is larger than 1, but bodywt does not exceed 100.

msleep %>% 
  select(name, sleep_total, brainwt, bodywt) %>% 
  filter(brainwt > 1, !bodywt > 100)

## # A tibble: 1 x 4
##   name  sleep_total brainwt bodywt
##   <chr>       <dbl>   <dbl>  <dbl>
## 1 Human        8.00    1.32   62.0

过滤掉空行

要过滤掉空行,你可以否定过滤器中的is.na()函数:
示例代码将删除conservationNA的所有行。

msleep %>% 
  select(name, conservation:sleep_cycle) %>% 
  filter(!is.na(conservation))

## # A tibble: 54 x 5
##    name                     conservation sleep_total sleep_rem sleep_cycle
##    <chr>                    <chr>              <dbl>     <dbl>       <dbl>
##  1 Cheetah                  lc                 12.1     NA          NA    
##  2 Mountain beaver          nt                 14.4      2.40       NA    
##  3 Greater short-tailed sh~ lc                 14.9      2.30        0.133
##  4 Cow                      domesticated        4.00     0.700       0.667
##  5 Northern fur seal        vu                  8.70     1.40        0.383
##  6 Dog                      domesticated       10.1      2.90        0.333
##  7 Roe deer                 lc                  3.00    NA          NA    
##  8 Goat                     lc                  5.30     0.600      NA    
##  9 Guinea pig               domesticated        9.40     0.800       0.217
## 10 Grivet                   lc                 10.0      0.700      NA    
## # ... with 44 more rows


Filtering across multiple columns

dplyr包有一些强大的变体可以一次过滤多个列:

*filter_all()将根据您的进一步说明过滤所有列
*filter_if()需要一个返回布尔值的函数来指示要过滤的列。如果是这样,那么将对这些列执行过滤器指令。
*filter_at()要求你在vars()参数中指定要进行过滤的列。

在这些情况下,有一般语法:首先指定哪些列,然后提及过滤器的条件。在许多情况下,您需要一个.运算符,该运算符指的是我们正在查看的值。

过滤所有

不可否认,msleep并不是展示这种能力的最佳数据库,但想象一下,你有一个包含几列的数据库,并且你想要选择在任一列中都有某个单词的所有行。以一个财务数据框为例,你想要选择带有'food'的所有行,是否在主类别栏,子类别栏,评论栏或你花费的地方提到了食物。
您可以在OR语句中包含4个不同条件的长过滤器语句。或者您只是过滤所有列的字符串“food”。

在下面的示例代码中,我在所有列中搜索字符串“Ca”。我想保留在任何变量中出现字符串“Ca”的行,所以我将条件包装在any_vars()中。
下面的代码基本上要求保留任何变量中包含模式“Ca”的行。

msleep %>% 
  select(name:order, sleep_total, -vore) %>% 
  filter_all(any_vars(str_detect(., pattern = "Ca")))

## # A tibble: 16 x 4
##    name              genus        order        sleep_total
##    <chr>             <chr>        <chr>              <dbl>
##  1 Cheetah           Acinonyx     Carnivora          12.1 
##  2 Northern fur seal Callorhinus  Carnivora           8.70
##  3 Vesper mouse      Calomys      Rodentia            7.00
##  4 Dog               Canis        Carnivora          10.1 
##  5 Roe deer          Capreolus    Artiodactyla        3.00
##  6 Goat              Capri        Artiodactyla        5.30
##  7 Guinea pig        Cavis        Rodentia            9.40
##  8 Domestic cat      Felis        Carnivora          12.5 
##  9 Gray seal         Haliochoerus Carnivora           6.20
## 10 Tiger             Panthera     Carnivora          15.8 
## 11 Jaguar            Panthera     Carnivora          10.4 
## 12 Lion              Panthera     Carnivora          13.5 
## 13 Caspian seal      Phoca        Carnivora           3.50
## 14 Genet             Genetta      Carnivora           6.30
## 15 Arctic fox        Vulpes       Carnivora          12.5 
## 16 Red fox           Vulpes       Carnivora           9.80

对于数值值也可以这样做:此代码将保留任何值低于0.1的行:

msleep %>%  
  select(name, sleep_total:bodywt) %>% 
  filter_all(any_vars(. < 0.1))

## # A tibble: 47 x 7
##    name           sleep_total sleep_rem sleep_cycle awake  brainwt  bodywt
##    <chr>                <dbl>     <dbl>       <dbl> <dbl>    <dbl>   <dbl>
##  1 Owl monkey           17.0      1.80       NA      7.00  1.55e-2 4.80e-1
##  2 Greater short~       14.9      2.30        0.133  9.10  2.90e-4 1.90e-2
##  3 Vesper mouse          7.00    NA          NA     17.0  NA       4.50e-2
##  4 Dog                  10.1      2.90        0.333 13.9   7.00e-2 1.40e+1
##  5 Roe deer              3.00    NA          NA     21.0   9.82e-2 1.48e+1
##  6 Guinea pig            9.40     0.800       0.217 14.6   5.50e-3 7.28e-1
##  7 Chinchilla           12.5      1.50        0.117 11.5   6.40e-3 4.20e-1
##  8 Star-nosed mo~       10.3      2.20       NA     13.7   1.00e-3 6.00e-2
##  9 African giant~        8.30     2.00       NA     15.7   6.60e-3 1.00e+0
## 10 Lesser short-~        9.10     1.40        0.150 14.9   1.40e-4 5.00e-3
## # ... with 37 more rows

any_vars()语句等价于OR,所以当然还有AND语句的等价句:all_vars()。 以下代码将保留所有值均高于1的所有行。

msleep %>%  
  select(name, sleep_total:bodywt, -awake) %>% 
  filter_all(all_vars(. > 1))

## # A tibble: 1 x 6
##   name  sleep_total sleep_rem sleep_cycle brainwt bodywt
##   <chr>       <dbl>     <dbl>       <dbl>   <dbl>  <dbl>
## 1 Human        8.00      1.90        1.50    1.32   62.0

Filter if

filter_all()函数有时会有点疯狂。 msleep数据集有一组睡眠和体重测量,其中一些数据丢失 - 我无法在那里添加数据。 但是前几组专栏只包含动物信息。 Vesper Mouse的遗体缺失,但这是我仍然可以挖掘并添加到数据框的信息,如果我想要的话。
所以想象一下,我想找出前几列中我们NA的所有数据行。 filter_all(any_vars(is.na(。)))将是非常无用的,因为它将返回27行,其中许多是测量部分中缺少的数据。

在这种情况下:filter_if()派上用场。 描述列都是字符列,而测量数据是数字。 所以使用filter_if()我可以指定我只想过滤字符变量。 在这种情况下,我只得到7行。

msleep %>% 
  select(name:order, sleep_total:sleep_rem) %>% 
  filter_if(is.character, any_vars(is.na(.)))

## # A tibble: 7 x 6
##   name            genus       vore  order          sleep_total sleep_rem
##   <chr>           <chr>       <chr> <chr>                <dbl>     <dbl>
## 1 Vesper mouse    Calomys     <NA>  Rodentia              7.00    NA    
## 2 Desert hedgehog Paraechinus <NA>  Erinaceomorpha       10.3      2.70 
## 3 Deer mouse      Peromyscus  <NA>  Rodentia             11.5     NA    
## 4 Phalanger       Phalanger   <NA>  Diprotodontia        13.7      1.80 
## 5 Rock hyrax      Procavia    <NA>  Hyracoidea            5.40     0.500
## 6 Mole rat        Spalax      <NA>  Rodentia             10.6      2.40 
## 7 Musk shrew      Suncus      <NA>  Soricomorpha         12.8      2.00

Similarly, you can add is.numeric, is.integer, is.double, is.logical, is.factor. If you have data columns, you can load the lubridate package, and use is.POSIXt or is.Date.

Filter at

其中一个更强大的函数是filter_at():它不会过滤所有列,也不需要你指定列的类型,你可以通过`vars()选择要发生更改的列。 论据。 这个参数允许在select语句中完成任何事情:所以你可以通过名称来引用它们,也可以通过逻辑数字函数,正则表达式等来引用它们(请参阅我的第一篇博客文章中的选择选项)。

第二个参数是选择的条件。 与上面的示例类似,如果所有列都需要返回TRUE(AND等效),则可以使用all_vars();如果只需要一个变量返回TRUE(OR等效),则可以使用any_vars()

示例:按名称引用列:

msleep %>% 
  select(name, sleep_total:sleep_rem, brainwt:bodywt) %>% 
  filter_at(vars(sleep_total, sleep_rem), all_vars(.>5))

## # A tibble: 2 x 5
##   name                 sleep_total sleep_rem brainwt bodywt
##   <chr>                      <dbl>     <dbl>   <dbl>  <dbl>
## 1 Thick-tailed opposum        19.4      6.60 NA       0.370
## 2 Giant armadillo             18.1      6.10  0.0810 60.0

Example: using another select option:

msleep %>% 
  select(name, sleep_total:sleep_rem, brainwt:bodywt) %>% 
  filter_at(vars(contains("sleep")), all_vars(.>5))

## # A tibble: 2 x 5
##   name                 sleep_total sleep_rem brainwt bodywt
##   <chr>                      <dbl>     <dbl>   <dbl>  <dbl>
## 1 Thick-tailed opposum        19.4      6.60 NA       0.370
## 2 Giant armadillo             18.1      6.10  0.0810 60.0
目录
相关文章
|
数据处理
航测数据处理教程(超详细)
航测数据处理教程(超详细)
180 1
|
3月前
|
数据挖掘 UED
数据分析的要求和作用
数据分析的要求
40 3
|
4月前
|
存储 算法 数据处理
|
4月前
|
机器学习/深度学习 数据采集 数据可视化
构建高效的数据管道:使用Python进行数据处理和分析
【8月更文挑战第24天】在信息爆炸的时代,数据是新的石油。本文将引导你如何利用Python构建一个高效的数据管道,从数据的获取、清洗到分析,最后实现可视化。我们将探索pandas、NumPy、matplotlib等库的强大功能,并通过实际案例加深理解。无论你是数据科学新手还是希望提升数据处理技能的开发者,这篇文章都将为你提供宝贵的洞见和实用技巧。
|
7月前
|
存储 数据挖掘 物联网
Python中的实时数据分析:构建流处理应用程序
【4月更文挑战第12天】本文介绍了Python在实时数据分析中的应用,包括实时数据分析的基本概念、Python的优势及基本流程。Python凭借丰富的库(如Pandas、NumPy)、强大的数据处理工具(如PySpark、Apache Kafka)和活跃的生态系统,成为实时数据分析的理想选择。文中通过社交媒体和物联网的数据分析案例展示了Python如何从数据获取、预处理、处理、存储到结果展示的全过程。通过学习和实践,读者可以掌握使用Python进行实时数据分析的技能。
147 3
|
7月前
|
并行计算 数据挖掘 数据处理
Pandas性能优化与高级功能:让数据处理更高效
【4月更文挑战第16天】本文探讨了如何优化Pandas的性能和利用其高级功能。关键的性能优化方法包括选择合适的数据类型、避免数据复制、使用向量化操作、优化查询和索引,以及探索并行计算。高级功能涉及分组聚合、窗口函数、数据透视表、缺失值处理和分类数据编码。通过这些技巧,可以更高效地处理大规模数据集。
|
7月前
|
SQL 数据处理
数据处理语言思考
数据处理语言思考
37 1
|
NoSQL Shell Linux
如何使用 Flupy 构建数据处理管道
如何使用 Flupy 构建数据处理管道
167 0
|
数据可视化 数据挖掘 数据处理
【数据篇】33 # 可视化数据处理的一般方法是什么?
【数据篇】33 # 可视化数据处理的一般方法是什么?
234 0
【数据篇】33 # 可视化数据处理的一般方法是什么?
|
数据采集 消息中间件 监控
功能介绍数据处理详解|学习笔记
快速学习功能介绍数据处理详解
功能介绍数据处理详解|学习笔记
下一篇
DataWorks