Using which() to filter out columns from a dataset

Viewed 41

I'm working with the mtcars dataset. I'm trying to create a new dataset which contains only the columns that are non-integer. To do this, I've tried several things, mainly trying to use lapply like so: > newdata <- lapply(mtcars, Negate(is.integer)) But this doesn't return what I need. In the exercise, it was told that which() can help us do this, so I ask - how? Thanks

4 Answers

You can do:

iris[sapply(iris, Negate(is.factor))]

    Sepal.Length Sepal.Width Petal.Length Petal.Width
1            5.1         3.5          1.4         0.2
2            4.9         3.0          1.4         0.2
3            4.7         3.2          1.3         0.2
4            4.6         3.1          1.5         0.2
5            5.0         3.6          1.4         0.2
6            5.4         3.9          1.7         0.4
7            4.6         3.4          1.4         0.3
8            5.0         3.4          1.5         0.2
9            4.4         2.9          1.4         0.2
10           4.9         3.1          1.5         0.1

Here, for illustration, I'm using the iris dataset and filtering out factors.

You could use Filter to select columns which are not integer.

Filter(Negate(is.integer), mtcars)
#Or explicitly mentioning non-integers
#Filter(function(x) !is.integer(x), mtcars)

In dplyr, we can use select_if

library(dplyr)
mtcars %>%  select_if(Negate(is.integer))
#mtcars %>%  select_if(~!is.integer(.))

To select those columns that appear as "integer" (according to your comment) you could select columns where all as.integer values correspond to the original ones using sapply.

mtcars[sapply(mtcars, function(i) all(as.integer(i) - i == 0))]
#                     cyl  hp vs am gear carb
# Mazda RX4             6 110  0  1    4    4
# Mazda RX4 Wag         6 110  0  1    4    4
# Datsun 710            4  93  1  1    4    1
# Hornet 4 Drive        6 110  1  0    3    1
# Hornet Sportabout     8 175  0  0    3    2
# Valiant               6 105  1  0    3    1
# Duster 360            8 245  0  0    3    4
# Merc 240D             4  62  1  0    4    2
# Merc 230              4  95  1  0    4    2
# Merc 280              6 123  1  0    4    4
# Merc 280C             6 123  1  0    4    4
# Merc 450SE            8 180  0  0    3    3
# Merc 450SL            8 180  0  0    3    3
# Merc 450SLC           8 180  0  0    3    3
# Cadillac Fleetwood    8 205  0  0    3    4
# Lincoln Continental   8 215  0  0    3    4
# Chrysler Imperial     8 230  0  0    3    4
# Fiat 128              4  66  1  1    4    1
# Honda Civic           4  52  1  1    4    2
# Toyota Corolla        4  65  1  1    4    1
# Toyota Corona         4  97  1  0    3    1
# Dodge Challenger      8 150  0  0    3    2
# AMC Javelin           8 150  0  0    3    2
# Camaro Z28            8 245  0  0    3    4
# Pontiac Firebird      8 175  0  0    3    2
# Fiat X1-9             4  66  1  1    4    1
# Porsche 914-2         4  91  0  1    5    2
# Lotus Europa          4 113  1  1    5    2
# Ford Pantera L        8 264  0  1    5    4
# Ferrari Dino          6 175  0  1    5    6
# Maserati Bora         8 335  0  1    5    8
# Volvo 142E            4 109  1  1    4    2

If the which is mandatory you could built it in like so:

mtcars[which(sapply(mtcars, function(i) all(as.integer(i) - i == 0)))]

We can use negate from purrr

library(purrr)
library(dplyr)
mtcars %>% 
     select_if(negate(is.integer))
Related