Ответ 1
Помимо использования опции, предложенной Мэттом Доуле, другой способ изменения классов столбцов выглядит следующим образом:
dat[, (cols) := lapply(.SD, factor), .SDcols=cols]
Используя оператор :=
, вы обновляете данные по ссылке. Проверьте, работает ли это:
> sapply(dat,class)
ID Quarter value
"factor" "factor" "numeric"
Как было предложено @MattDowle в комментариях, вы также можете использовать комбинацию for(...) set(...)
следующим образом:
for (col in cols) set(dat, j = col, value = factor(dat[[col]]))
который даст тот же результат. Третий вариант:
for (col in cols) dat[, (col) := factor(dat[[col]])]
В меньших наборах данных параметр for(...) set(...)
примерно в три раза быстрее, чем параметр lapply
(но это не имеет особого значения, поскольку это небольшой набор данных). В больших наборах данных (например, 2 миллиона строк) каждый из этих подходов занимает примерно столько же времени. Для тестирования на более крупном наборе данных я использовал:
dat <- data.table(ID=c(rep("A", 1e6), rep("B",1e6)),
Quarter=c(1:1e6, 1:1e6),
value=rnorm(10))
Иногда вам придется делать это по-другому (например, когда числовые значения сохраняются как фактор). Тогда вы должны использовать что-то вроде этого:
dat[, (cols) := lapply(.SD, function(x) as.integer(as.character(x))), .SDcols=cols]
ПРЕДУПРЕЖДЕНИЕ: Следующее объяснение - не data.table
- способ выполнения действий. Данному не обновляется по ссылке, потому что копия создается и сохраняется в памяти (как указано в @Frank), что увеличивает использование памяти. Это больше подходит для объяснения работы with=FALSE
.
Если вы хотите изменить классы столбцов так же, как и с фреймворком данных, вы должны добавить with = FALSE
следующим образом:
dat[, cols] <- lapply(dat[, cols, with = FALSE], factor)
Проверьте, работает ли это:
> sapply(dat,class)
ID Quarter value
"factor" "factor" "numeric"
Если вы не добавите with = FALSE
, datatable будет оценивать dat[, cols]
как вектор. Проверьте разницу в выходе между dat[, cols]
и dat[, cols, with=FALSE]
:
> dat[, cols]
[1] "ID" "Quarter"
> dat[, cols, with=FALSE]
ID Quarter
1: A 1
2: A 2
3: A 3
4: A 4
5: A 5
6: B 1
7: B 2
8: B 3
9: B 4
10: B 5