Ich habe einen großen Datenrahmen mit einer Faktorspalte, die ich in drei Faktorspalten aufteilen muss, indem ich die Faktornamen durch ein Trennzeichen aufspalte. Hier ist mein aktueller Ansatz, der mit einem großen Datenrahmen ist sehr langsam (manchmal mehrere Millionen Zeilen):Beschleunigen Sie `strsplit`, wenn die mögliche Ausgabe bekannt ist
data <- readRDS("data.rds")
data.df <- reshape2:::melt.array(data)
head(data.df)
## Time Location Class Replicate Population
##1 1 1 LIDE.1.S 1 0.03859605
##2 2 1 LIDE.1.S 1 0.03852957
##3 3 1 LIDE.1.S 1 0.03846853
##4 4 1 LIDE.1.S 1 0.03841260
##5 5 1 LIDE.1.S 1 0.03836147
##6 6 1 LIDE.1.S 1 0.03831485
Rprof("str.out")
cl <- which(names(data.df)=="Class")
Classes <- do.call(rbind, strsplit(as.character(data.df$Class), "\\."))
colnames(Classes) <- c("Species", "SizeClass", "Infected")
data.df <- cbind(data.df[,1:(cl-1)],Classes,data.df[(cl+1):(ncol(data.df))])
Rprof(NULL)
head(data.df)
## Time Location Species SizeClass Infected Replicate Population
##1 1 1 LIDE 1 S 1 0.03859605
##2 2 1 LIDE 1 S 1 0.03852957
##3 3 1 LIDE 1 S 1 0.03846853
##4 4 1 LIDE 1 S 1 0.03841260
##5 5 1 LIDE 1 S 1 0.03836147
##6 6 1 LIDE 1 S 1 0.03831485
summaryRprof("str.out")
$by.self
self.time self.pct total.time total.pct
"strsplit" 1.34 50.00 1.34 50.00
"<Anonymous>" 1.16 43.28 1.16 43.28
"do.call" 0.04 1.49 2.54 94.78
"unique.default" 0.04 1.49 0.04 1.49
"data.frame" 0.02 0.75 0.12 4.48
"is.factor" 0.02 0.75 0.02 0.75
"match" 0.02 0.75 0.02 0.75
"structure" 0.02 0.75 0.02 0.75
"unlist" 0.02 0.75 0.02 0.75
$by.total
total.time total.pct self.time self.pct
"do.call" 2.54 94.78 0.04 1.49
"strsplit" 1.34 50.00 1.34 50.00
"<Anonymous>" 1.16 43.28 1.16 43.28
"cbind" 0.14 5.22 0.00 0.00
"data.frame" 0.12 4.48 0.02 0.75
"as.data.frame.matrix" 0.08 2.99 0.00 0.00
"as.data.frame" 0.08 2.99 0.00 0.00
"as.factor" 0.08 2.99 0.00 0.00
"factor" 0.06 2.24 0.00 0.00
"unique.default" 0.04 1.49 0.04 1.49
"unique" 0.04 1.49 0.00 0.00
"is.factor" 0.02 0.75 0.02 0.75
"match" 0.02 0.75 0.02 0.75
"structure" 0.02 0.75 0.02 0.75
"unlist" 0.02 0.75 0.02 0.75
"[.data.frame" 0.02 0.75 0.00 0.00
"[" 0.02 0.75 0.00 0.00
$sample.interval
[1] 0.02
$sampling.time
[1] 2.68
Gibt es eine Möglichkeit, diesen Vorgang zu beschleunigen? Ich stelle fest, dass es eine kleine (< 5) Anzahl von jeder der Kategorien "Species", "SizeClass" und "Infiziert" gibt, und ich weiß, was diese im Voraus sind.
Anmerkungen:
stringr::str_split_fixed
führt diese Aufgabe, aber nicht schneller- Der Datenrahmen zunächst durch Aufruf
reshape::melt
auf einem Array erzeugt tatsächlich in derClass
und seine zugehörigen Ebene eine Dimension sind. Wenn es einen schnelleren Weg gibt, von hier nach hier zu kommen, großartig. data.rds
bei http://dl.getdropbox.com/u/3356641/data.rds
Das ist schnell! Obwohl du 'as.character (Class)' verwenden musst. Können Sie die Spalten als Faktoren in demselben Befehl zurückgeben? –
Sie können in Faktor konvertieren, aber tun Sie es als zweite Zeile nach. Die Verwendung von as.factor in demselben Aufruf, der ein "by" -Argument enthält, verlangsamt notwendigerweise den Prozess. –
@NoamRoss, schöner Fang auf dem 'as.character'. Aktualisierter Code plus ein paar zusätzliche Schritte –