Convertir*algunas*clases de columna en data.table
(2)
Además de usar la opción sugerida por Matt Dowle, otra forma de cambiar las clases de columna es la siguiente:
dat[, (cols) := lapply(.SD, factor), .SDcols = cols]
Al utilizar el operador :=
, se actualiza la base de datos por referencia. Una comprobación de si esto funcionó:
> sapply(dat,class)
ID Quarter value
"factor" "factor" "numeric"
Como sugirió @MattDowle en los comentarios, también puede usar una combinación de for(...) set(...)
siguiente manera:
for (col in cols) set(dat, j = col, value = factor(dat[[col]]))
Lo que dará el mismo resultado. Una tercera alternativa es:
for (col in cols) dat[, (col) := factor(dat[[col]])]
En conjuntos de datos más pequeños, la opción for(...) set(...)
es aproximadamente tres veces más rápida que la opción lapply
(pero eso no importa, porque es un conjunto de datos pequeño). En conjuntos de datos más grandes (por ejemplo, 2 millones de filas), cada uno de estos enfoques lleva aproximadamente la misma cantidad de tiempo. Para las pruebas en un conjunto de datos más grande, utilicé:
dat <- data.table(ID=c(rep("A", 1e6), rep("B",1e6)),
Quarter=c(1:1e6, 1:1e6),
value=rnorm(10))
A veces, tendrá que hacerlo un poco diferente (por ejemplo, cuando los valores numéricos se almacenan como un factor). Entonces tienes que usar algo como esto:
dat[, (cols) := lapply(.SD, function(x) as.integer(as.character(x))), .SDcols = cols]
ADVERTENCIA: La siguiente explicación no es la data.table
de datos de data.table
hacer las cosas. La base de datos no se actualiza por referencia porque se realiza una copia y se almacena en la memoria (como lo señala @Frank), lo que aumenta el uso de la memoria. Es más una adición para explicar el funcionamiento de with = FALSE
.
Cuando desee cambiar las clases de columna de la misma manera que lo haría con un marco de datos, debe agregar with = FALSE
siguiente manera:
dat[, cols] <- lapply(dat[, cols, with = FALSE], factor)
Una comprobación de si esto funcionó:
> sapply(dat,class)
ID Quarter value
"factor" "factor" "numeric"
Si no agrega with = FALSE
, datatable evaluará dat[, cols]
como un vector. Verifique la diferencia en la salida entre dat[, cols]
y 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
Quiero convertir un subconjunto de data.table cols a una nueva clase. Hay una pregunta popular aquí ( Convertir clases de columna en data.table ) pero la respuesta crea un nuevo objeto, en lugar de operar en el objeto inicial.
Tomemos este ejemplo:
dat <- data.frame(ID=c(rep("A", 5), rep("B",5)), Quarter=c(1:5, 1:5), value=rnorm(10))
cols <- c(''ID'', ''Quarter'')
¿Cuál es la mejor manera de convertir solo las cols
columnas a (por ejemplo) un factor? En un data.frame normal puedes hacer esto:
dat[, cols] <- lapply(dat[, cols], factor)
pero eso no funciona para una tabla de datos, y tampoco lo hace esto
dat[, .SD := lapply(.SD, factor), .SDcols = cols]
Un comentario en la pregunta vinculada de Matt Dowle (desde diciembre de 2013) sugiere lo siguiente, que funciona bien, pero parece un poco menos elegante.
for (j in cols) set(dat, j = j, value = factor(dat[[j]]))
¿Existe actualmente una mejor respuesta de data.table (es decir, más corto + no genera una variable de contador), o debo usar el + rm(j)
?
Puedes usar .SDcols
:
dat[, cols] <- dat[, lapply(.SD, factor), .SDcols=cols]