В 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))))