21
votes

I need to select all columns that are not numeric. I can select all numeric columns easily using select_if:

mtcars %>% select_if(is.numeric)

What if I want to select non-numeric columns? I tried:

mtcars %>% select_if(!is.numeric)

But I got error message below:

Error in !is.numeric : invalid argument type

Thanks a lot for help!

3

3 Answers

37
votes

You can use purrr's negate() which is included if you use library(tidyverse) rather than just library(dplyr)

library(tidyverse)
iris %>% select_if(negate(is.numeric))
7
votes

You can use a purrr-style anonymous function, provided you have a reasonably recent version of dplyr:

library(dplyr)

iris %>% select_if(~!is.numeric(.x)) %>% head()
#>   Species
#> 1  setosa
#> 2  setosa
#> 3  setosa
#> 4  setosa
#> 5  setosa
#> 6  setosa

or the old-style funs notation still works, e.g.

iris %>% select_if(funs(!is.numeric(.))) %>% head()
#>   Species
#> 1  setosa
#> 2  setosa
#> 3  setosa
#> 4  setosa
#> 5  setosa
#> 6  setosa
2
votes

One possible solution could be:

df[, !(names(df) %in% names(df %>% select_if(is.numeric)))]

Example:
df <- data.frame(
  name = c( "a", "b", "c", "d" ),
  last_name = c( "r", "t", "s", "b" ),
  x = c( 3, 2, 1, 2 ),
  y = c( 4, 3, 4, 3 ),
  z = c( 8, 9, 6, 7 ) , stringsAsFactors = FALSE)
> df[, !(names(df) %in% names(df %>% select_if(is.numeric)))]
#  name last_name
#1    a         r
#2    b         t
#3    c         s
#4    d         b