У меня есть несколько столбцов, которые я хотел бы удалить из фрейма данных. Я знаю, что мы можем удалить их по отдельности, используя что-то вроде:
df$x <- NULL
Но я надеялся сделать это с меньшим количеством команд.
Кроме того, я знаю, что я мог бы отбросить столбцы, используя целочисленную индексацию следующим образом:
df <- df[ -c(1, 3:6, 12) ]
Но я обеспокоен тем, что относительное положение моих переменных может измениться.
Учитывая, насколько мощный R, я подумал, что может быть лучший способ, чем отбрасывать каждый столбец один за другим.
df#drop(var_name)
, и вместо этого нам нужно сделать эти сложные обходные пути?Ответы:
Вы можете использовать простой список имен:
Или, в качестве альтернативы, вы можете составить список тех, которые нужно сохранить, и сослаться на них по имени:
РЕДАКТИРОВАТЬ: Для тех, кто еще не знаком с
drop
аргументом функции индексации, если вы хотите сохранить один столбец в качестве фрейма данных, вы должны:drop=TRUE
(или не упоминая об этом) отбросит ненужные измерения и, следовательно, вернет вектор со значениями столбцаy
.источник
DF[,keeps]
вместоDF[keeps]
?Также есть
subset
команда, полезная, если вы знаете, какие столбцы вы хотите:ОБНОВЛЕНО после комментария @hadley: Чтобы удалить столбцы a, c, вы можете сделать:
источник
subset
функции R была опция типа «allbut = FALSE», которая «инвертирует» выбор, когда установлен в значение «ИСТИНА», то есть сохраняет все столбцы, кроме тех, которые вselect
списке.df[c("a", "c")]
subset
команды, когда вам не нужно ставить кавычки вокруг имен столбцов - я думаю, я не против набрать несколько дополнительных символов только для того, чтобы избежать цитирования имен :)subset
внутри других функций.вероятно, проще всего, или для нескольких переменных:
Или, если вы имеете дело с
data.table
s ( как удалить столбец по имени в data.table? ):или для нескольких переменных
источник
within(df, rm(x))
является на сегодняшний день самым чистым раствором. Учитывая, что это возможно, любой другой ответ кажется излишне сложным на порядок.within(df, rm(x))
это не будет работать, если есть дублированные столбцы, названныеx
вdf
.df <- data.frame(x = 1, y = 2); names(df) <- c("x", "x"); within(df, rm(x))
возвратdata.frame(x = 2, x = 2)
.within()
которая является мощной, но также использует NSE. В примечании на странице справки четко указано, что для программирования следует использовать достаточную осторожность.Вы можете использовать
%in%
как это:источник
DF[ , !(names(DF) %in% drops)]
identical(post_time_1, post_time_2) [1] TRUE
= Dlist (NULL) также работает:
источник
Если вы хотите удалить столбцы по ссылке и избежать внутреннего копирования, связанного с этим,
data.frames
вы можете использоватьdata.table
пакет и функцию:=
Вы можете передать имена векторных символов в левую часть
:=
оператора иNULL
как RHS.Если вы хотите предварительно определить имена как символьный вектор вне вызова
[
, оберните имя объекта в()
или{}
заставьте LHS быть оцененным в вызывающей области, а не как имя в пределах областиDT
.Вы также можете использовать
set
, что позволяет избежать накладных расходов[.data.table
, а также работает наdata.frames
!источник
Существует потенциально более мощная стратегия, основанная на том факте, что grep () возвращает числовой вектор. Если у вас длинный список переменных, как у меня в одном из моего набора данных, некоторые переменные заканчиваются на «.A», а другие заканчиваются на «.B», и вам нужны только те, которые заканчиваются на «.A» (вместе со всеми переменными, которые не соответствуют ни одному шаблону, сделайте это:
Для рассматриваемого случая, на примере Joris Meys, он может быть не таким компактным, но это будет:
источник
drops
в первую очередь какpaste0("^", drop_cols, "$")
, это станет намного лучше (читай: более компактно) сsapply
:DF[ , -sapply(drops, grep, names(DF))]
Еще один
dplyr
ответ. Если ваши переменные имеют некоторую общую структуру именования, вы можете попробоватьstarts_with()
. НапримерЕсли вы хотите удалить последовательность переменных во фрейме данных, вы можете использовать
:
. Например, если вы хотите удалитьvar2
,var3
и все переменные между ними, вы бы просто оставилиvar1
:источник
select()
, таких какcontains()
илиmatches()
, которые также принимают регулярные выражения.Другая возможность:
или
источник
setdiff
является оптимальным, особенно в случае очень большого количества столбцов.df <- df[ , -which(grepl('a|c', names(df)))]
Вывод:
Вывод:
источник
Решение Dplyr
Я сомневаюсь, что здесь будет много внимания, но если у вас есть список столбцов, которые вы хотите удалить, и вы хотите сделать это в
dplyr
цепочке, которую я используюone_of()
вselect
предложении:Вот простой, воспроизводимый пример:
Документацию можно найти, запустив
?one_of
или здесь:http://genomicsclass.github.io/book/pages/dplyr_tutorial.html
источник
Из интереса это указывает на одну из странных множественных синтаксических несоответствий R. Например, для данных с двумя столбцами:
Это дает фрейм данных
но это дает вектор
Это все объясняется,
?[
но это не совсем ожидаемое поведение. Ну, по крайней мере, не для меня ...источник
Вот
dplyr
способ сделать это:Мне нравится это, потому что это интуитивно понятно и понятно без аннотации и устойчиво к изменению положения столбцов во фрейме данных. Он также следует векторизации, используемой
-
для удаления элементов.источник
%<>%
оператор для замены входного объекта, к которому его можно упроститьdf %<>% select(-col.to.drop.1, -col.to.drop.2, ..., -col.to.drop.6)
dplyr
ними может быть проще сгруппировать их и поставить только один минус:df.cut <- df %>% select(-c(col.to.drop.1, col.to.drop.2, ..., col.to.drop.n))
Я продолжаю думать, что должна быть лучшая идиома, но для вычитания столбцов по имени я склонен делать следующее:
источник
df[,-match(c("e","f"),names(df))]
-
?В пакете
dropNamed()
Бернда Бишля есть функция,BBmisc
которая делает именно это.Преимущество состоит в том, что он избегает повторения аргумента фрейма данных и, таким образом, подходит для передачи
magrittr
(так же, какdplyr
подходы):источник
Другое решение, если вы не хотите использовать @adley выше: если «COLUMN_NAME» - это имя столбца, который вы хотите удалить:
источник
COLUMN_NAME
его нетdf
(проверьте себя:)df<-data.frame(a=1,b=2)
. (3)df[,names(df) != "COLUMN_NAME"]
проще и не страдают от (2)Помимо того, что было
select(-one_of(drop_col_names))
продемонстрировано в предыдущих ответах, есть несколько другихdplyr
вариантов удаления столбцов,select()
которые не включают в себя определение всех определенных имен столбцов (с использованием образца данных dplyr starwars для некоторого разнообразия в именах столбцов):Если вам нужно отбросить столбец, который может существовать или не существовать во фрейме данных, приведем небольшой поворот,
select_if()
который, в отличие от использованияone_of()
, не выдастUnknown columns:
предупреждение, если имя столбца не существует. В этом примере bad_column не является столбцом во фрейме данных:источник
Укажите фрейм данных и строку имен, разделенных запятыми, для удаления:
Использование :
источник
Найдите индекс столбцов, которые вы хотите удалить, используя
which
. Дайте этим индексам отрицательный знак (*-1
). Затем подмножество тех значений, которые будут удалять их из кадра данных. Это пример.источник
Если у вас большой
data.frame
и мало памяти, используйте[
. , , , илиrm
иwithin
чтобы удалить столбцыdata.frame
, так какsubset
в настоящее время (R 3.6.2) с использованием дополнительной памяти - рядом намек на руководство , чтобы использовать вsubset
интерактивном режиме .источник