Как удалить столбец по имени в 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)
}
Для 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 хранятся в виде списка столбцов, вы можете пропустить запятую. Вы также можете добавить его, однако тогда вам нужно будет назначить их в список NULL
s, DF[, c("col1", "col2", "col3")] <- list(NULL)
,