R dplyr: удаление нескольких столбцов

У меня есть фрейм данных и список столбцов в этом фрейме данных, который я бы хотел удалить. В качестве примера можно использовать набор данных iris. Я хотел бы оставить Sepal.Length и Sepal.Width и использовать только оставшиеся столбцы. Как это сделать, используя select или select_ из пакета dplyr?

Вот что я пробовал до сих пор:

drop.cols <- c('Sepal.Length', 'Sepal.Width')
iris %>% select(-drop.cols)

Ошибка в -drop.cols: недопустимый аргумент для унарного оператора

iris %>% select_(.dots = -drop.cols)

Ошибка в -drop.cols: недопустимый аргумент для унарного оператора

iris %>% select(!drop.cols)

Ошибка в! drop.cols: недопустимый тип аргумента

iris %>% select_(.dots = !drop.cols)

Ошибка в! drop.cols: недопустимый тип аргумента

Я чувствую, что мне не хватает чего-то очевидного, потому что это похоже на довольно полезную операцию, которая уже должна существовать. В Github кто-то опубликовал аналогичную проблему, и Хэдли сказал использовать "отрицательную индексацию". То, что (я думаю), я пробовал, но безрезультатно. Любые предложения?

Ответ 1

Проверьте справку по select_vars. Это дает вам дополнительные идеи о том, как с этим работать.

В вашем случае:

iris %>% select(-one_of(drop.cols))

Ответ 2

попробуйте

## Notice the lack of quotes
iris %>% select (-c(Sepal.Length, Sepal.Width))

Ответ 3

Помимо select(-one_of(drop.cols)), есть пара других опций для удаления столбцов с использованием select(), которые не включают определение всех определенных имен столбцов (с использованием примеров данных звездных звезд dplyr для еще большего разнообразия в именах столбцов):

starwars %>% 
  select(-(name:mass)) %>%        # the range of columns from 'name' to 'mass'
  select(-contains('color')) %>%  # any column name that contains 'color'
  select(-starts_with('bi')) %>%  # any column name that starts with 'bi'
  select(-ends_with('er')) %>%    # any column name that ends with 'er'
  select(-matches('^f.+s$')) %>%  # any column name matching the regex pattern
  select_if(~!is.list(.)) %>%     # not by column name but by data type
  head(2)

# A tibble: 2 x 2
homeworld species
  <chr>     <chr>  
1 Tatooine  Human  
2 Tatooine  Droid 

Ответ 4

Мы можем попробовать

iris %>% 
      select_(.dots= setdiff(names(.),drop.cols))

Ответ 5

Будьте осторожны с функцией select(), потому что она используется как в пакетах dplyr, так и в MASS, поэтому, если MASS загружен, select() может работать неправильно. Чтобы узнать, какие пакеты загружены, введите sessionInfo() и найдите его в разделе "Другие прикрепленные пакеты:". Если он загружен, введите detach( "package:MASS", unload = TRUE ), и ваша функция select() должна работать снова.

Ответ 6

Если в именах столбцов есть специальный символ, select или select_ могут работать не так, как ожидалось. Это свойство dplyr использования ".". Чтобы обратиться к набору данных в вопросе, для решения этой проблемы можно использовать следующую строку:

drop.cols <- c('Sepal.Length', 'Sepal.Width')
  iris %>% .[,setdiff(names(.),drop.cols)]

Ответ 7

Другой способ - преобразовать нежелательные столбцы в NULL, это позволяет избежать встроенных скобок:

head(iris,2) %>% mutate_at(drop.cols, ~NULL)
#   Petal.Length Petal.Width Species
# 1          1.4         0.2  setosa
# 2          1.4         0.2  setosa

Ответ 8

Вы можете попробовать

iris %>% select(-!!drop.cols)