Идентификация и преобразование в числовой / целочисленный

#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