Tengo una secuencia de comandos que lee datos de un archivo CSV en data.table
ay luego divide el texto en una columna en varias columnas nuevas. Actualmente estoy usando las funciones lapply
y strsplit
para hacer esto. He aquí un ejemplo:
library("data.table")
df = data.table(PREFIX = c("A_B","A_C","A_D","B_A","B_C","B_D"),
VALUE = 1:6)
dt = as.data.table(df)
# split PREFIX into new columns
dt$PX = as.character(lapply(strsplit(as.character(dt$PREFIX), split="_"), "[", 1))
dt$PY = as.character(lapply(strsplit(as.character(dt$PREFIX), split="_"), "[", 2))
dt
# PREFIX VALUE PX PY
# 1: A_B 1 A B
# 2: A_C 2 A C
# 3: A_D 3 A D
# 4: B_A 4 B A
# 5: B_C 5 B C
# 6: B_D 6 B D
En el ejemplo anterior, la columna PREFIX
se divide en dos columnas nuevas PX
y PY
en el carácter "_".
Aunque esto funciona bien, me preguntaba si hay una forma mejor (más eficiente) de hacer esto usando data.table
. Mis conjuntos de datos reales tienen> = 10M + filas, por lo que la eficiencia de tiempo / memoria se vuelve realmente importante.
ACTUALIZAR:
Siguiendo la sugerencia de @ Frank, creé un caso de prueba más grande y usé los comandos sugeridos, pero stringr::str_split_fixed
lleva mucho más tiempo que el método original.
library("data.table")
library("stringr")
system.time ({
df = data.table(PREFIX = rep(c("A_B","A_C","A_D","B_A","B_C","B_D"), 1000000),
VALUE = rep(1:6, 1000000))
dt = data.table(df)
})
# user system elapsed
# 0.682 0.075 0.758
system.time({ dt[, c("PX","PY") := data.table(str_split_fixed(PREFIX,"_",2))] })
# user system elapsed
# 738.283 3.103 741.674
rm(dt)
system.time ( {
df = data.table(PREFIX = rep(c("A_B","A_C","A_D","B_A","B_C","B_D"), 1000000),
VALUE = rep(1:6, 1000000) )
dt = as.data.table(df)
})
# user system elapsed
# 0.123 0.000 0.123
# split PREFIX into new columns
system.time ({
dt$PX = as.character(lapply(strsplit(as.character(dt$PREFIX), split="_"), "[", 1))
dt$PY = as.character(lapply(strsplit(as.character(dt$PREFIX), split="_"), "[", 2))
})
# user system elapsed
# 33.185 0.000 33.191
Por tanto, el str_split_fixed
método tarda unas 20 veces más.
stringr
paquete, este es el comando:str_split_fixed(PREFIX,"_",2)
. No respondo porque no he probado la aceleración ... O, en un solo paso:dt[,c("PX","PY"):=data.table(str_split_fixed(PREFIX,"_",2))]