Is there any simple/elegant (=tidy) way to select all numeric columns and one character column (specified by column name)? I was trying to use the select_if for this purpose, but I didn’t found a solution.
My workaround is to construct programmatically a vector of column names and use the select afterwards. But I am interesting to see any simpler solutions.
I found a workaround in this post that can be adapted to your problem:
library("dplyr")
#Fake data
myData = data.frame(a = 1:10, b = 1:10, c = LETTERS[1:10], d = 1:10, e = letters[1:10], stringsAsFactors = F)
#Filtering
myData %>% select_if(function(col) all(col == .$e) | is.numeric(col))
a b d e
1 1 1 1 a
2 2 2 2 b
3 3 3 3 c
4 4 4 4 d
5 5 5 5 e
6 6 6 6 f
7 7 7 7 g
8 8 8 8 h
9 9 9 9 i
10 10 10 10 j
However .... I'm not happy with the way that code looks and tried a long time to get a more elegant solution but tidyverse is not letting me
This works individually:
myData %>% select_if(is.numeric)
a b d
1 1 1 1
2 2 2 2
3 3 3 3
4 4 4 4
5 5 5 5
6 6 6 6
7 7 7 7
8 8 8 8
9 9 9 9
10 10 10 10
myData %>% select_if(names(.) == "e")
e
1 a
2 b
3 c
4 d
5 e
6 f
7 g
8 h
9 i
10 j
A OR-statement works, it is just that you can't access the name of column in select_if, just the value
library(tidyverse)
#Fake data
myData = data.frame(a = 1:10, b = 1:10, c = LETTERS[1:10], d = 1:10, e = letters[1:10], stringsAsFactors = F)
# A or statement works
myData %>%
mutate(c = as.factor(c)) %>%
select_if(~ is.numeric(.) | is.factor(.))
#> a b c d
#> 1 1 1 A 1
#> 2 2 2 B 2
#> 3 3 3 C 3
#> 4 4 4 D 4
#> 5 5 5 E 5
#> 6 6 6 F 6
#> 7 7 7 G 7
#> 8 8 8 H 8
#> 9 9 9 I 9
#> 10 10 10 J 10
# You can't access the names of the column
# this does not works
myData %>%
select_if(~ names(.) == "e")
#> Error in selected[[i]] <- eval_tidy(.p(column, ...)): l'argument de remplacement est de longueur nulle
# equivalent of
myData %>%
select_if(function(x) names(x) == "e")
#> Error in selected[[i]] <- eval_tidy(.p(column, ...)): l'argument de remplacement est de longueur nulle
# this works because . is myData here
myData %>%
select_if(names(.) == "e")
#> e
#> 1 a
#> 2 b
#> 3 c
#> 4 d
#> 5 e
#> 6 f
#> 7 g
#> 8 h
#> 9 i
#> 10 j
# equivalent of
myData %>%
select_if(names(myData) == "e")
#> e
#> 1 a
#> 2 b
#> 3 c
#> 4 d
#> 5 e
#> 6 f
#> 7 g
#> 8 h
#> 9 i
#> 10 j
Interesting ... but as @kbzsl said, there should be a readable and tidy approach given the power of tidyverse. Your approach, as several others in this post do the job, but none seem intuitive, which goes against the mantra of the tidyverse lol