В dplyr выберите с каплей не работает

В dplyr я хочу исключить столбцы, содержащие слово "мусор", но не может быть ни одного столбца, содержащего слово "мусор". В этом случае dplyr должен возвращать все столбцы. Но он ничего не возвращает. См. Ниже unit test.

df<-data.frame(name=paste("name",1:5), age=1:5)
str(df)
# 'data.frame': 5 obs. of  2 variables:
# $ name: Factor w/ 5 levels "name 1","name 2",..: 1 2 3 4 5
# $ age : int  1 2 3 4 5
df1<-df%>%select(-contains("junk"))
str(df1)
# 'data.frame': 5 obs. of  0 variables

Где я иду не так?

Ответы

Ответ 1

Он работает, если вы ставите everything() перед -contains() внутри select:

library(dplyr) # 0.4.1
df %>% select(everything(), -contains("junk"))
#    name age
#1 name 1   1
#2 name 2   2
#3 name 3   3
#4 name 4   4
#5 name 5   5

Однако я согласен с тем, что было бы более интуитивно, если бы оно работало без необходимости everything().

Ответ 2

Изменить: Это исправлено в новейшей версии dplyr. См. Также здесь.

Оригинальное сообщение: Только для полноты, вот причина этой ошибки. Функция contains внутренне использует grep("junk", names(df)). Конечно, это возвращает integer(0).

dplyr:::contains(names(df), "junk")
## integer(0)

Теперь -integer(0), конечно, совпадает с +integer(0), а вызов select(df, integer(0)) явно возвращает фрейм данных с 0 столбцами.

select(df, integer(0))
## data frame with 0 columns and 5 rows

Ответ 3

Это работает, но это не очень.

df %>% select(which(!(names(.) %in% grep("junk", names(.), value=T))))