根据多个属性条件选择列

9

我正在尝试找出如何有效地使用 dplyr::select_if 选择列。在dplyr 0.70中,starwars数据集是一个不错的数据集。

> starwars
# A tibble: 87 x 13
                 name height  mass    hair_color  skin_color eye_color birth_year gender homeworld species     films  vehicles starships
                <chr>  <int> <dbl>         <chr>       <chr>     <chr>      <dbl>  <chr>     <chr>   <chr>    <list>    <list>    <list>
 1     Luke Skywalker    172    77         blond        fair      blue       19.0   male  Tatooine   Human <chr [5]> <chr [2]> <chr [2]>
 2              C-3PO    167    75          <NA>        gold    yellow      112.0   <NA>  Tatooine   Droid <chr [6]> <chr [0]> <chr [0]>
 3              R2-D2     96    32          <NA> white, blue       red       33.0   <NA>     Naboo   Droid <chr [7]> <chr [0]> <chr [0]>
 4        Darth Vader    202   136          none       white    yellow       41.9   male  Tatooine   Human <chr [4]> <chr [0]> <chr [1]>
 5        Leia Organa    150    49         brown       light     brown       19.0 female  Alderaan   Human <chr [5]> <chr [1]> <chr [0]>
 6          Owen Lars    178   120   brown, grey       light      blue       52.0   male  Tatooine   Human <chr [3]> <chr [0]> <chr [0]>
 7 Beru Whitesun lars    165    75         brown       light      blue       47.0 female  Tatooine   Human <chr [3]> <chr [0]> <chr [0]>
 8              R5-D4     97    32          <NA>  white, red       red         NA   <NA>  Tatooine   Droid <chr [1]> <chr [0]> <chr [0]>
 9  Biggs Darklighter    183    84         black       light     brown       24.0   male  Tatooine   Human <chr [1]> <chr [0]> <chr [1]>
10     Obi-Wan Kenobi    182    77 auburn, white        fair blue-gray       57.0   male   Stewjon   Human <chr [6]> <chr [1]> <chr [5]>

现在假设我想选择只包含整数的列。这段代码可以很好地实现:

library(dplyr)

starwars %>%
  select_if(is.numeric)

但是如果我想根据多个条件进行选择,该怎么办呢?例如,我可能希望选择数字和字符列:

starwars %>%
  select_if(c(is.numeric, is.character))

或者我想要所有数值和 name 列:

starwars %>%
  select_if(name, is.character)

以上两个示例均不起作用,因此我想知道如何实现我在这里概述的内容。


1
相关问题和答案请点击此处 - aosmith
5个回答

5

对于第一个例子:

starwars %>%
  select_if(function(col) {is.numeric(col) | is.character(col)})

我会尽力帮助您翻译中文,以下是需要翻译的内容:

这段文字直接摘自RDocumentation页面。

对于第二个:

toKeep <- sapply(starwars, is.numeric)
starwars %>%
  select("name", names(toKeep)[as.numeric(toKeep) == 1])

我目前无法让某些东西变得更漂亮,但我相信有更好的方法 :)


确实,在RDocumentation上可以找到这个,但这并不能回答所有数字和“name”列的问题。你有什么想法吗? - boshek
一个选项:starwars %> group_by(name)%> select_if(is.numeric)。但那有点丑。 - boshek
是的,抱歉,那比我想象中花了更长的时间。请查看更新后的答案。 - psychOle

4
从版本1.0.0开始,如在新闻中提到的那样,

如果您要这样做,可能应该包括安装说明,直到版本在CRAN上。 - boshek

2
你可以编写自己的函数:
 to_keep <- function(x) is.numeric(x) | is.character(x)
 starwars %>% select_if(to_keep)

或者你可以使用“引用风格的lambda函数”:
starwars %>% select_if(funs(is.numeric(.) | is.character(.)))

我不知道如何将不同的列选择逻辑组合在一起,因此我会使用混合方法(即使这并不是很优雅,因为您需要重复初始数据集):

 starwars %>%
    select("name") %>%
    bind_cols(select_if(starwars, funs(is.numeric(.) | is.character(.))))

1
你有想法如何选择名称和所有数值数据列吗? - boshek

2

使用优雅的tidyverse语法,其中~代表匿名函数,在使用select_if函数时可能会有所帮助:

require(tidyverse)

# numeric and character columns
starwars %>% select_if(~ is.numeric(.) | is.character(.)) 

# all numeric AND the name column
starwars %>% select(name, where(is.numeric))

根据tidyverse的创建者,建议将一些谓词函数(例如is.numeric)在select中使用时包装在where()中。


0

对于第二部分(获取数字和名称列):

to_keep <- c(starwars %>% select_if(is.numeric) %>% names,"name")
starwars %>% select(one_of(to_keep))  

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接