前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >数据处理第3部分:选择行的基本和高级的方法

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

作者头像
用户1359560
发布2018-09-29 17:08:35
1.3K0
发布2018-09-29 17:08:35
举报
文章被收录于专栏:生信小驿站生信小驿站

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


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

代码语言:javascript
复制
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 !=.

代码语言:javascript
复制
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()稍微短一些

代码语言:javascript
复制
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的所有行。

代码语言:javascript
复制
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

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

代码语言:javascript
复制
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顺序的动物的行。

代码语言:javascript
复制
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%似乎是逻辑但它不起作用。

代码语言:javascript
复制
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)))`。

代码语言:javascript
复制
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订单的一部分。

代码语言:javascript
复制
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()

代码语言:javascript
复制
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.

代码语言:javascript
复制
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的所有行。

代码语言:javascript
复制
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”的行。

代码语言:javascript
复制
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的行:

代码语言:javascript
复制
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的所有行。

代码语言:javascript
复制
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行。

代码语言:javascript
复制
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()

示例:按名称引用列:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018.09.09 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Basic row filters
    • Filtering rows based on a numeric variable
      • Filtering based on a exact character variable matches
        • 根据正则表达式过滤行
          • 基于多种条件的过滤
            • 过滤掉空行
            • Filtering across multiple columns
              • 过滤所有
                • Filter if
                  • Filter at
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档