Я активно использую Tidyverse, но для некоторых проектов мне нужна скорость data.table. Пока я понимаю большую часть синтаксиса DT, но я хочу отбросить неиспользуемые уровни в data.table без использования mutate_if
.
С dplyr
я могу использовать mutate_if(dataframe, is.factor, droplevels)
и все. Однако я не могу обойтись с data.table.
Я пытался применить этот ответ , используя dataframe[, (.SD) := droplevels(.SD), .SDcols = sapply(dataframe, is.factor)]
Выдает следующую ошибку: Error in
[. Data.table (DT_, ,
: = ((.SD), droplevels(.SD)), .SDcols = sapply(DT_, :
LHS of := isn't column names ('character') or positions ('integer' or 'numeric')
.
Я ожидаю, что получу тот же результат, что и в mutate_if
, без использования Tidyverse.
UPDATE
Я принял G. Гротендик ответил , потому что код был больше, чем я ожидал.
Пример, который он использовал:
library(data.table)
DT <- data.table(a = 1:5,
b = factor(1:5, levels = 1:10),
c = factor(6:10, levels = 1:10))
Данные, которые я использовал для этого примера, были следующие:
set.seed(42)
DT1 = data.table(
A = LETTERS[1:10],
B = c(1:10),
C = factor(sample(LETTERS, 10), levels = LETTERS),
D = factor(sample(LETTERS, 10), levels = LETTERS)
)
Интересующие столбцы:
> DT1[, C]
[1] Q E A J D R Z O G V
Levels: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
> DT1[, D]
[1] Y E N T R O C I D Z
Levels: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
И результаты
# with base
DT1 = droplevels(DT1)
# or by reference
DT1[, (names(DT1)) := droplevels(.SD)]
Со следующим выводом:
> DT1[, C]
[1] Q E A J D R Z O G V
Levels: A D E G J O Q R V Z
> DT1[, D]
[1] Y E N T R O C I D Z
Levels: C D E I N O R T Y Z
Спасибо всем за ваши ответы, это было быстро!