2016-07-01 9 views
0

Ich habe zwei Datensätze - TEST Ende ZUG. TEST ist eine Teilmenge von TRAIN. Unter Verwendung der Spalten "prod" und "clnt" muss ich alle Zeilen in TRAIN finden, die mit TEST korrespondieren (es ist eine bis mehrere Übereinstimmungen). Dann mache ich eine zeitliche Analyse der jeweiligen Werte der Spalte "Reihenfolge" von TEST (erste Spalte "Woche" ist die Zeit).Schleife aus zeilenweise Unterteilung der Daten zu beseitigen

Also nehme ich die erste Reihe von TRAIN, ich vergleiche alle Zeilen von TEST, ob einige von ihnen die gleiche Kombination von "prod" und "clnt" enthalten und die entsprechenden Werte von "order" in TS notieren. Normalerweise habe ich null bis etwa zehn Werte in TS pro Zeile von TRAIN. Dann mache ich einige Berechnungen über TS (in diesem künstlichen Fall nur Mittelwert (TS)) und notiere das Ergebnis sowie die "Id" der Reihe von TEST in einem Datensatz Subm.

Der Algorithmus funktioniert, aber weil ich Millionen von Reihen in TRAIN und TEST habe, brauche ich es so schnell wie möglich und vor allem, um die Schleife loszuwerden, die der langsamste Teil ist. Vermutlich habe ich auch mit der data.frame-Deklaration/Verwendung verstimmt, bin mir aber nicht sicher.

set.seed(42) 
NumObsTrain=100000 # this can be as much as 70 000 000 
NumObsTest=10000 # this can be as much as 6 000 000 

#create the TRAIN data set 
train1=floor(runif(NumObsTrain, min=0, max=NumObsTrain+1)) 
train1=matrix(train1,ncol = 2) 
train=cbind(8,train1) #week 
train=rbind(train,cbind(9,train1)) #week 
train=cbind(train,runif(NumObsTrain,min=1,max=10)) #order 
train=cbind(c(1:nrow(train)),train)# id number of each row 
colnames(train)=c("id","week","prod","clnt","order") 
train=as.data.frame(train) 
train=train[sample(nrow(train)),] # reflush the rows of train 

# Create the TEST dataset 
test=train[1:NumObsTest,] 
test[,"week"][1:{NumObsTest/2}]=10 
test[,"week"][{(NumObsTest/2)+1}:NumObsTest]=11 

TS=numeric(length = 10) 
id=c(1:NumObsTest*2) 
order=c(1:NumObsTest*2) 
Subm=data.frame(id,order) 
ptm <- proc.time() 

# This is the loop 
for (i in 1:NumObsTest){ 
    Subm$id[i]=test$id[i] 
    TS=train$order[train$clnt==test$clnt[i]&train$prod==test$prod[i]] 
    Subm$order[i]=mean(TS) 
} 
proc.time() - ptm 
+2

Bitte geben Sie ein [minimal funktionierendes Beispiel] (http://stackoverflow.com/help/mcve) an. – sebastianmm

+1

Ihre Erklärung ist ein wenig unklar. Ich habe deinen Code ausgeführt, aber ich bin mir nicht sicher, was ich sehen soll. Warum hat 'TS' nur zwei Werte am Ende? (Zumindest wenn ich es versuchte) Aus der Beschreibung am Anfang, scheint, wie Sie alle Zeilen von TRAIN wollen, die auch in TEST erscheinen, nur die 'prod' und' clnt' Spalten betrachtend. Wenn das der Fall ist, gibt 'dplyr :: semi_join (train, test, by = c (" prod "," clnt "))' Ihnen diesen Teil der Antwort. –

+0

@LuisUsie, Das ist ein künstliches Beispiel und es funktioniert so, wie es sein soll. Es ist normal, nur zwei Werte in TS zu haben. Du hast Recht, dass ich alle Reihen von TRAIN, die in TEST erscheinen, habe. "prod" und "clnt" Das einzige Problem ist die geringe Geschwindigkeit, die durch die Verwendung der Schleife am Ende verursacht wird. Ich weiß, dass einige Vektorisierung notwendig ist, aber ich bin immer noch Newby in R. Also werde ich den Rat über dplyr versuchen. – kalinfirst

Antwort

2

Im Folgenden wird data.frame mit allen (prod, clnt) und order Kombinationen schaffen, so dass sie dann die Gruppe von prod und clnt, dann nehmen Sie den Mittelwert der Größenordnung von jeder Gruppe. Das Endergebnis ist das Fehlen der id, und aus irgendeinem Grund haben Sie mehr Daten in Ihrem final data.frame, was ich nicht herausfinden kann warum. Aber die order Ergebnisse sind korrekt.

newtrain <- train[, 3:5] 
newtest <- test[, c(1, 3:4)] 
x <- dplyr::inner_join(newtest, newtrain) 
y <- dplyr::group_by(x, prod, clnt) 
z <- dplyr::summarise(y, mean(order)) 
Verwandte Themen