#r #data.table
#r #данные.таблица
Вопрос:
У меня есть ситуация, когда мне нужно просмотреть символьные данные и преобразовать их в числовые или целочисленные. Мне нужно выполнить эту операцию с data.table, и она должна быть sofastthatIdontnoticeit при работе с data.table, которая содержит ~ 1000 столбцов и 1e6 строк. Там много недостающих или разреженных данных, так что это сбивающий с толку элемент.
fread
из data.table
пакета делает это невероятно быстро и хорошо протестировано из файла csv (среди других опций).
Есть ли способ применить идентификатор столбца, используемый в fread
, к существующему data.table
?
В противном случае, вот подход, который я рассматривал (который все еще слишком медленный).:
Фиктивные данные:
library(data.table)
size = 1e6
resample <- function(x,size = 1e6) sample(x,size,replace = TRUE)
text <- c("Canada","Peru","Australia",
"Angola","France","", NA_character_)
text2 <- c("Oh Canada.","Arriba Peru.",
"Australia?","Vive la France.")
numerics <- rnorm(1e6)
dt <- data.table(
id = as.character(1:1e6),
i1 = resample(c(as.character(c(0:5,NA)),"")), # sometimes just blank
i2 = resample(c(as.character(c(100:500,NA)))),
n1 = as.character(round(rnorm(1e6),3)),
t1 = resample(text),
t2 = resample(text2)
)
str(dt)
Мой подход до сих пор заключается в том, чтобы использовать grep
для проверки столбцов альфа и литерал .
, а затем написать короткую функцию для применения as.*
в соответствии с определением.
decide <- data.frame(
vars = names(dt),
character = unlist(lapply(dt, function(x) length(grep("[a-z]",x)))),
numeric = unlist(lapply(dt, function(x) length(grep("[.]",x))))
)
what_is_it <- function(character, numeric) {
if(character == 0 amp; numeric == 0) {
return("as.integer")
}
if(character > 0) {
return("as.character")
}
if(numeric > 0 amp; character == 0) {
return("as.numeric")
}
}
decide$fun <- apply(decide[-1], 1, function(x) what_is_it(x[1],x[2]))
for(var in decide$vars) {
fun <- get(decide$fun[decide$vars == var])
dt[, (var) := fun(get(var))]
dt[]
}
system.time(source("https://gist.githubusercontent.com/1beb/183511b51d615751860204344a02c799/raw/91fcee73f24596ac6bdec00edaad944b5b1b7713/quick_convert.R"))
Работает на моей машине со скоростью около 3,5 секунд, но только для 7 столбцов.
Комментарии:
1.
type.convert
может быть полезно здесь2.
system.time(for (j in names(dt) set(dt, j = j, value = type.convert(dt[[j]])))
0,79 секунды. Неплохо. Должен быть ответ, хотя!
Ответ №1:
Как указано пользователем 20650. Ответ таков type.convert