У меня проблема с использованием data.table: как преобразовать классы столбцов? Вот простой пример: с data.frame у меня нет проблем с его преобразованием, с data.table я просто не знаю как:
df <- data.frame(ID=c(rep("A", 5), rep("B",5)), Quarter=c(1:5, 1:5), value=rnorm(10))
#One way: http://stackoverflow.com/questions/2851015/r-convert-data-frame-columns-from-factors-to-characters
df <- data.frame(lapply(df, as.character), stringsAsFactors=FALSE)
#Another way
df[, "value"] <- as.numeric(df[, "value"])
library(data.table)
dt <- data.table(ID=c(rep("A", 5), rep("B",5)), Quarter=c(1:5, 1:5), value=rnorm(10))
dt <- data.table(lapply(dt, as.character), stringsAsFactors=FALSE)
#Error in rep("", ncol(xi)) : invalid 'times' argument
#Produces error, does data.table not have the option stringsAsFactors?
dt[, "ID", with=FALSE] <- as.character(dt[, "ID", with=FALSE])
#Produces error: Error in `[<-.data.table`(`*tmp*`, , "ID", with = FALSE, value = "c(1, 1, 1, 1, 1, 2, 2, 2, 2, 2)") :
#unused argument(s) (with = FALSE)
Я упускаю здесь что-то очевидное?
Обновление из-за сообщения Мэтью: раньше я использовал старую версию, но даже после обновления до 1.6.6 (версия, которую я использую сейчас) я все равно получаю сообщение об ошибке.
Обновление 2: Допустим, я хочу преобразовать каждый столбец класса «фактор» в «символьный» столбец, но не знаю заранее, какой столбец принадлежит к какому классу. С помощью data.frame я могу делать следующее:
classes <- as.character(sapply(df, class))
colClasses <- which(classes=="factor")
df[, colClasses] <- sapply(df[, colClasses], as.character)
Могу ли я сделать что-то подобное с data.table?
Обновление 3:
sessionInfo () R версия 2.13.1 (2011-07-08) Платформа: x86_64-pc-mingw32 / x64 (64-разрядная)
locale:
[1] C
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] data.table_1.6.6
loaded via a namespace (and not attached):
[1] tools_2.13.1
источник
data.table
методах отличаются от тех, для которых они предназначеныdata.frame
#Produces error
. +1 в любом случае. Я не получаю ошибок, какая у вас версия? Однако в этой области есть проблема, она уже поднималась, FR № 1224 и FR № 1493 являются приоритетными для решения. Однако ответ Андри - лучший способ.invalid times argument
ошибке? У меня работает нормально. Какая у тебя версия?Ответы:
Для одного столбца:
Использование
lapply
иas.character
:источник
convcols
столбцов.dt[,lapply(.SD,as.numeric),.SDcols=convcols]
почти мгновенно, в то время какdt[,convcols:=lapply(.SD,as.numeric),.SDcols=convcols]
R почти зависает, поэтому я предполагаю, что делаю это неправильно. Спасибоset()
например,for (col in names_factors) set(dt, j=col, value=as.factor(dt[[col]]))
[конечная цитата]Попробуй это
источник
Filter
функцию для идентификации столбцов, например:changeCols<- names(Filter(is.character, DT))
changeCols <- names(DT)[sapply(DT, is.character)]
.Подняв комментарий Мэтта Доула к ответу Geneorama ( https://stackoverflow.com/a/20808945/4241780 ), чтобы сделать его более очевидным (как рекомендуется), вы можете использовать
for(...)set(...)
.Создано 12 февраля 2020 г. пакетом REPEX (v0.3.0)
См. Еще один комментарий Мэтта на https://stackoverflow.com/a/33000778/4241780 для получения дополнительной информации.
Редактировать.
Как отметил Эспен и в
help(set)
,j
может быть «имя (я) столбца (символ) или номер (а) (целое число), которому будет присвоено значение, если столбец (я) уже существует»). Такnames_factors <- c(1L, 3L)
тоже будет работать.источник
names_factors
здесь. Я предполагаю, что это взято из stackoverflow.com/a/20808945/1666063, поэтомуnames_factors = c('fac1', 'fac2')
в данном случае это имена столбцов, но это также могут быть номера столбцов, например 1; ncol (dt), который преобразовал бы все столбцыЭто ПЛОХОЙ способ сделать это! Я оставляю этот ответ только на тот случай, если он решит другие странные проблемы. Эти лучшие методы, вероятно, частично являются результатом новых версий data.table ... поэтому стоит задокументировать этот трудный путь. Кроме того, это хороший пример
eval
substitute
синтаксиса для синтаксиса.что дает вам
источник
set()
например,for (col in names_factors) set(dt, j=col, value=as.factor(dt[[col]]))
set
это более уместно.for(...)set(...)
здесь: stackoverflow.com/a/33000778/403310Я пробовал несколько подходов.
, или иным образом
источник
Я предлагаю более общий и безопасный способ сделать это,
Функция
..
гарантирует, что мы получаем переменную вне области data.table; set_colclass установит классы ваших столбцов. Вы можете использовать это так:источник
Если у вас есть список имен столбцов в data.table, вы хотите изменить класс do:
источник
dt[, c(convert_to_character) := lapply(.SD, as.character), .SDcols=convert_to_character]
назначение по ссылке, а не используйте более медленное назначение data.frame.пытаться:
источник