Как удалить столбец по имени в data.table?

Чтобы избавиться от столбца с именем "Foo" в data.frame, Я могу сделать:

df <- df[-grep('foo', colnames(df))]

Однако однажды df превращается в data.table объект, нет способа просто удалить столбец.

Пример:

df <- data.frame(id = 1:100, foo = rnorm(100))
df2 <- df[-grep('foo', colnames(df))] # works
df3 <- data.table(df)
df3[-grep('foo', colnames(df3))] 

Но как только он преобразуется в data.table объект, это больше не работает.

8 ответов

Решение

Любое из следующего удалит колонку foo из таблицы data.table df3:

# Method 1 (and preferred as it takes 0.00s even on a 20GB data.table)
df3[,foo:=NULL]

df3[, c("foo","bar"):=NULL]  # remove two columns

myVar = "foo"
df3[, (myVar):=NULL]   # lookup myVar contents

# Method 2a -- A safe idiom for excluding (possibly multiple)
# columns matching a regex
df3[, grep("^foo$", colnames(df3)):=NULL]

# Method 2b -- An alternative to 2a, also "safe" in the sense described below
df3[, which(grepl("^foo$", colnames(df3))):=NULL]

data.table также поддерживает следующий синтаксис:

## Method 3 (could then assign to df3, 
df3[, !"foo", with=FALSE]  

хотя, если вы действительно хотите удалить столбец "foo" от df3 (в отличие от просто печати вида df3 минус столбец "foo") вы действительно хотите использовать метод 1 вместо.

(Обратите внимание, что если вы используете метод, основанный на grep() или же grepl() нужно установить pattern="^foo$" скорее, чем "foo", если вы не хотите столбцы с такими именами, как "fool" а также "buffoon" (т.е. те, которые содержат foo как подстрока), которая также должна быть сопоставлена ​​и удалена.)

Менее безопасные варианты, отлично подходит для интерактивного использования:

Следующие две идиомы также будут работать - если df3 содержит соответствие столбца "foo" - но потерпит неудачу, возможно, неожиданным образом, если этого не произойдет. Если, например, вы используете любой из них для поиска несуществующего столбца "bar" вы получите нулевую строку в data.table.

Как следствие, они действительно лучше всего подходят для интерактивного использования, когда можно, например, захотеть отобразить таблицу данных за вычетом любых столбцов с именами, содержащими подстроку. "foo", Для целей программирования (или если вы действительно хотите удалить столбец (столбцы) из df3 Методы 1, 2a и 2b - действительно лучшие варианты.

# Method 4a:
df3[, -grep("^foo$", colnames(df3)), with=FALSE]

# Method 4b: 
df3[, !grepl("^foo$", colnames(df3)), with=FALSE]

Вы также можете использовать set для этого, что позволяет избежать накладных расходов [.data.table в петлях:

dt <- data.table( a=letters, b=LETTERS, c=seq(26), d=letters, e=letters )
set( dt, j=c(1L,3L,5L), value=NULL )
> dt[1:5]
   b d
1: A a
2: B b
3: C c
4: D d
5: E e

Если вы хотите сделать это по имени столбца, which(colnames(dt) %in% c("a","c","e")) должен работать на j,

Я просто делаю это во фрейме данных таким образом:

DT$col = NULL

Работает быстро и, насколько я вижу, проблем не вызывает.

ОБНОВЛЕНИЕ: не самый лучший метод, если ваш DT очень большой, как использование $<- Оператор приведет к копированию объекта. Так что лучше используйте:

DT[, col:=NULL]

Очень простой вариант, если у вас есть много отдельных столбцов для удаления в таблице данных, и вы хотите избежать ввода всех имен столбцов #careadviced

dt <- dt[, -c(1,4,6,17,83,104), with =F]

Вместо этого будут удалены столбцы на основе номера столбца.

Очевидно, что он не так эффективен, потому что он обходит преимущества data.table, но если вы работаете с менее чем 500 000 строк, он работает нормально

Предположим, что ваш DT имеет столбцы col1, col2, col3, col4, col5, coln,

Чтобы удалить их подмножество:

vx <- as.character(bquote(c(col1, col2, col3, coln)))[-1]
DT[, paste0(vx):=NULL]

Вот способ, когда вы хотите установить количество столбцов в NULL, если их имена столбцов являются функцией для вашего использования:)

deleteColsFromDataTable <- function (train, toDeleteColNames) {

   for (myNm in toDeleteColNames)

   train <- train [,(myNm):=NULL,with=F]

   return (train)

}

DT[,c:=NULL] # remove column c

Для data.table назначение столбца в NULL удаляет его:

DT[,c("col1", "col1", "col2", "col2")] <- NULL
^
|---- Notice the extra comma if DT is a data.table

... что эквивалентно:

DT$col1 <- NULL
DT$col2 <- NULL
DT$col3 <- NULL
DT$col4 <- NULL

Эквивалент для data.frame:

DF[c("col1", "col1", "col2", "col2")] <- NULL
      ^
      |---- Notice the missing comma if DF is a data.frame

В. Почему в версии для data.table есть запятая, а в версии data.frame нет запятой?

О. Поскольку data.frames хранятся в виде списка столбцов, вы можете пропустить запятую. Вы также можете добавить его, однако тогда вам нужно будет назначить их в список NULLs, DF[, c("col1", "col2", "col3")] <- list(NULL),

Другие вопросы по тегам