Ich habe ein Skript, das Daten aus einer CSV-Datei in eine einliest data.table
und dann den Text in einer Spalte in mehrere neue Spalten aufteilt. Ich benutze derzeit die lapply
und strsplit
Funktionen, um dies zu tun. Hier ist ein Beispiel:
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
Im obigen Beispiel wird die Spalte PREFIX
in zwei neue Spalten PX
und PY
mit dem Zeichen "_" aufgeteilt.
Obwohl dies gut funktioniert, habe ich mich gefragt, ob es einen besseren (effizienteren) Weg gibt, dies mit zu tun data.table
. Meine realen Datensätze haben> = 10M + Zeilen, daher wird die Zeit- / Speichereffizienz wirklich wichtig.
AKTUALISIEREN:
Auf @ Franks Vorschlag hin habe ich einen größeren Testfall erstellt und die vorgeschlagenen Befehle verwendet, aber das stringr::str_split_fixed
dauert viel länger als die ursprüngliche Methode.
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
Die str_split_fixed
Methode dauert also etwa 20-mal länger.
stringr
Paket verwenden, ist dies der Befehl :str_split_fixed(PREFIX,"_",2)
. Ich antworte nicht, weil ich die Beschleunigung nicht getestet habe ... Oder in einem Schritt:dt[,c("PX","PY"):=data.table(str_split_fixed(PREFIX,"_",2))]