Ich hatte gehofft, jemand könnte helfen, ich versuche, eine Anwendungsfunktion zu beschleunigen, und ich habe ein paar Tricks versucht, aber es ist immer noch sehr langsam und ich fragte mich, ob Jeder hatte noch mehr Vorschläge.Beschleunigung der Anwendung einer Funktion auf eindeutige Werte in R
Ich habe Daten wie folgt:
myData= data.frame(ident=c(3,3,4,4,4,4,4,4,4,4,4,7,7,7,7,7,7,7),
group=c(7,7,7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8),
significant=c(1,1,0,0,0,0,0,0,0,0,0,1,1,0,1,0,0,0),
year=c(2003,2002,2001,2008,2010,2007,2007,2008,2006,2012,2008,
2012,2006,2001,2014,2012,2004,2007),
month=c(1,1,9,12,3,2,4,3,9,5,12,8,11,3,1,6,3,1),
subReport=c(0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0),
prevReport=c(1,1,0,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1))
und ich möchte mit einem Datenrahmen wie dies am Ende:
results=data.frame(ident=c(3,4,7),
significant=c(1,0,1),
prevReports=c(2,6,7),
subReport=c(0,1,0),
group=c(7,7,8))
Um dies zu tun, ich den Code unten geschrieben und es zu tun schnell i habe versucht, in Datentabellen umzuwandeln und rbindlist anstelle von rbind zu verwenden, was ich in einigen Threads vorgeschlagen habe. Ich habe auch versucht, ParLapply, aber ich finde immer noch, dass der Prozess ziemlich langsam ist, (Ich mache das auf etwa 250.000 Datenpunkte).
dt<-data.table(myData)
results<-NULL
ApplyModel <- function (id,data) {
dtTemp<-dt[dt$ident== id,]
if(nrow(dtTemp)>=1){
prevReport = if(sum(dtTemp$prevReport)>=1) sum(dtTemp$prevReport) else 0
subsequentReport = if(sum(dtTemp$subReport)>=1) 1 else 0
significant = as.numeric(head(dtTemp$sig,1))
group = head(dtTemp$group,1)
id= as.numeric(head(dtTemp$id,1))
output<-cbind(id, significant ,prevReport,subsequentReport ,group)
output<-output[!duplicated(output[,1]),]
print(output)
results <- rbindlist(list(as.list(output)))
}
}
results<-lapply(unique(dt$ident), ApplyModel)
results<-as.data.frame(do.call(rbind, results))
Alle Vorschläge, wie dies beschleunigt werden könnte, wären sehr willkommen! Ich denke, dass es mit der Teilmenge zu tun ist, möchte ich die Funktion auf eine Teilmenge basierend auf einem eindeutigen Wert anwenden, aber ich denke, dass lapply ist wirklich mehr für die Anwendung einer Funktion auf jeden Wert, so Subsetting besiegt das Objekt etwas ...
Erstellen 'first' scheint übertrieben; 'myAny' sollte auf Integer anstelle von Float erzwingen; und der korrekte Weg, um in eine data.table zu transformieren, ist 'setDT (mydata)' (ohne irgendeine '<-'-Zuweisung). Schließlich ist die Syntax, die für dieses Beispiel benötigt wird, nicht besonders; Sie machen es nur schwerer als nötig zu lesen, indem Sie Whitespace weglassen und 'by = ident' nach Position statt nach name übergeben. Das sind keine großen Probleme; nur um dich wissen zu lassen. Auch bezüglich des Erlernens der Syntax könntest du zu den Vignetten verlinken: https://github.com/Rdatatable/data.table/wiki/Getting-started – Frank
Vielen Dank für die Hinweise und dafür, mich auf setDT() zu verweisen. Ob zuerst definiert werden soll und ob Argumentnamen angegeben werden und wo Leerzeichen gesetzt werden, ist Geschmackssache. Ich denke, dass myAny wahrscheinlich überhaupt nicht gezwungen werden sollte, da booleans wahrscheinlich die Werte am besten widerspiegeln. Zur Frage der Syntax von data.tables: Wir werden wahrscheinlich zustimmen, dass data.table eine eigene DSL hat, die kompakt, auf den Punkt und nützlich ist. Das ursprüngliche Poster scheint mit grundlegenden R zu kämpfen, und ich rate Anfängern, grundlegendes R zuerst zu lernen, bevor Sie in DSLs innerhalb von R wie Datentabelle, ggplot2, reguläre Ausdrücke tauchen. – Bernhard
weiter: Das ist wieder eine Frage des Geschmacks, aber ich glaube, dass Lernen data.table sollte kommen, nachdem man Basis-R wie tapply gelernt hat, aggregieren, doBy und dergleichen. Die Verknüpfung mit den Vignetten ist eine großartige Ergänzung. – Bernhard