Tengo una secuencia de comandos que lee datos de un archivo CSV en data.tableay luego divide el texto en una columna en varias columnas nuevas. Actualmente estoy usando las funciones lapplyy strsplitpara 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 PREFIXse divide en dos columnas nuevas PXy PYen 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_fixedlleva 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_fixedmétodo tarda unas 20 veces más.
stringrpaquete, 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))]