Чтобы избавиться от столбца с именем "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
, это больше не работает.
Любое из следующего удалит столбец 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"
, вы получите таблицу данных с нулевой строкой.
Как следствие, они действительно лучше всего подходят для интерактивного использования, где можно, например, хотеть отображать таблицу данных минус любые столбцы с именами, содержащими подстроку "foo"
. Для целей программирования (или если вы хотите фактически удалить столбцы из df3
, а не из его копии), методы 1, 2a и 2b действительно лучшие варианты.
# Method 4a:
df3[, -grep("^foo$", colnames(df3)), with=FALSE]
# Method 4b:
df3[, !grepl("^foo$", colnames(df3)), with=FALSE]
-grep
против !grepl
.
grepl()
изначально, и он не работал, так как столбцы data.table не могут быть проиндексированы логическим вектором. Но теперь я понимаю, что grepl()
можно grepl()
работать, обернув его с помощью which()
, чтобы он возвращал целочисленный вектор.
Вы также можете использовать 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
.
data.table
1.11.8, если вы хотите сделать это по имени столбца, вы можете сделать непосредственно rm.col = c("a","b")
и dt[, (rm.col):=NULL]
Я просто делаю это в виде кадра:
DT$col = NULL
Работает быстро и насколько я мог видеть, не вызывает никаких проблем.
UPDATE: не лучший метод, если ваш DT очень большой, поскольку использование оператора $<-
приведет к копированию объекта. Поэтому лучше использовать:
DT[, col:=NULL]
Очень простая опция, если у вас есть много отдельных столбцов для удаления в таблице данных, и вы хотите избежать ввода всех имен столбцов #careadviced
dt <- dt[, -c(1,4,6,17,83,104), with =F]
Вместо этого удаляются столбцы на основе номера столбца.
Это явно не так эффективно, потому что он обходит преимущества data.table, но если вы работаете с менее чем 500 000 строк, он отлично работает
with=F
Предположим, что у вашего dt есть столбцы col1
, col2
, col3
, col4
, col5
, coln
.
Чтобы удалить подмножество из них:
vx <- as.character(bquote(c(col1, col2, col3, coln)))[-1]
DT[, paste0(vx):=NULL]
DT[,c:=NULL] # remove column c
Вот путь, когда вы хотите установить # столбцов в NULL с учетом их имен столбцов функция для вашего использования:)
deleteColsFromDataTable < - function (train, toDeleteColNames) {
for (myNm in toDeleteColNames)
train <- train [,(myNm):=NULL,with=F]
return (train)
}
Для таблицы данных. присвоение столбцу 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
Q. Почему в версии для таблицы data.table есть запятая и нет запятой в файле data.frame?
а. Поскольку data.frames хранятся в виде списка столбцов, вы можете пропустить запятую. Вы также можете добавить его, но тогда вам нужно будет назначить их списку NULL
s, DF[, c("col1", "col2", "col3")] <- list(NULL)
.
data.frames
где строки и столбцы будут переключаться. Это было бы нелогично.
dt
вместоdf3
...