R dplyr:删除多列


96

我有一个数据框和要删除的该数据框中的列列表。让我们以iris数据集为例。我想删除Sepal.LengthSepal.Width仅使用剩余的列。如何使用包装selectselect_dplyr包装中取出?

到目前为止,这是我尝试过的方法:

drop.cols <- c('Sepal.Length', 'Sepal.Width')
iris %>% select(-drop.cols)

-drop.cols中的错误:一元运算符的参数无效

iris %>% select_(.dots = -drop.cols)

-drop.cols中的错误:一元运算符的参数无效

iris %>% select(!drop.cols)

!drop.cols中的错误:参数类型无效

iris %>% select_(.dots = !drop.cols)

!drop.cols中的错误:参数类型无效

我觉得我缺少一些明显的东西,因为这些似乎是应该已经存在的非常有用的操作。在Github上,有人发布了类似的问题,哈德利说要使用“负索引”。那是我尝试过的(我认为),但无济于事。有什么建议?

Answers:


127

检查有关select_vars的帮助。这为您提供了一些有关如何使用此功能的额外想法。

在您的情况下:

iris %>% select(-one_of(drop.cols))

谢谢。出于某种原因,这适用于iris,但不适用于我的实际数据框(这iris是一个玩具示例)。我的数据框包含4558行和147列。我收到的错误消息是Error in eval(x$expr, data, x$env) : variable names are limited to 10000 bytes。知道为什么会这样吗?
Navaneethan Santhanam'3

1
嗯,看来我在弄错。我不小心使用select_vars而不是select。现在,它可以完美运行了!
Navaneethan Santhanam 2016年

5
我们应该在哪里找到像这样的内置函数one_of?除非我缺少某些内容,否则它不会出现在包装文档(help(package='dplyr'))中。
geotheory,2016年

4
@geotheory,实际上一个已被记录。见help(one_of, package = "dplyr")。至少它在软件包版本0.5.0中。但是,当其中一个软件包有更新时,阅读Hadley发布的博客会有所帮助。某些功能记录在其他功能中。不幸的是,这需要阅读所有文档,当我想要该功能无法立即发现或无法实现的功能时,我通常会这样做。
phiver '16

10
谢谢。从文档方面,您如何首先了解这些功能?
geotheory,2016年


37

除此以外,select(-one_of(drop.cols))还有其他一些用于删除列的选项,这些选项select()不涉及定义所有特定的列名称(使用dplyr starwars示例数据获取更多的列名称):

starwars %>% 
  select(-(name:mass)) %>%        # the range of columns from 'name' to 'mass'
  select(-contains('color')) %>%  # any column name that contains 'color'
  select(-starts_with('bi')) %>%  # any column name that starts with 'bi'
  select(-ends_with('er')) %>%    # any column name that ends with 'er'
  select(-matches('^f.+s$')) %>%  # any column name matching the regex pattern
  select_if(~!is.list(.)) %>%     # not by column name but by data type
  head(2)

# A tibble: 2 x 2
homeworld species
  <chr>     <chr>  
1 Tatooine  Human  
2 Tatooine  Droid 

select_if(~!is.list(.))相当于select_if(is.list(.))
Jasha

3
在这种情况下~,purrr是定义匿名函数的简写,它不是另一个符号。例如这两个意思是一样的function(x) {!is.list(x)}~!is.list(.)。认为~是...的简写function(.)
SlyFox

8

请谨慎使用该select()函数,因为它同时在dplyr和MASS软件包中使用,因此,如果加载了MASS,select()可能无法正常工作。若要找出要加载的软件包sessionInfo(),请在“其他附加的软件包:”部分中键入并寻找它。如果已加载,请键入detach( "package:MASS", unload = TRUE ),然后您的select()函数应会再次运行。


12
或者,您可以直接在包名称空间中访问该函数dplyr::select()
Triamus

2
我经常遇到这个问题。现在,我通常在脚本顶部定义一个新函数dselect <- dplyr::select()
filups19年

5

我们可以尝试

iris %>% 
      select_(.dots= setdiff(names(.),drop.cols))

谢谢@akrun,它运行良好。但是,鉴于周围的炒作dplyr使基本分析任务易于阅读和编写的能力,令我感到失望的是,实际的解决方案似乎是一种解决方法。
Navaneethan Santhanam

@NavaneethanSanthanam实际上,one_of另一种解决方案是要走的路。我忘了
akrun

3

另一种方法是将不需要的列更改为NULL,这避免了嵌入括号:

head(iris,2) %>% mutate_at(drop.cols, ~NULL)
#   Petal.Length Petal.Width Species
# 1          1.4         0.2  setosa
# 2          1.4         0.2  setosa

如果没有列,也不会发出警告。
skoz

3

如果你有在列名的特殊字符,无论是selectselect_可能无法正常工作。的该属性dplyr使用"."。要引用问题中的数据集,可以使用以下行来解决此问题:

drop.cols <- c('Sepal.Length', 'Sepal.Width')
  iris %>% .[,setdiff(names(.),drop.cols)]

不鼓励仅使用代码的答案。请提供一些有关答案如何工作以及与已有答案有何不同的解释。
拉尔夫·斯塔伯纳

谢谢!!上面的其他解决方案都没有出于这个确切原因而工作。
Marty999 '19

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.