2016-08-03 15 views
2

Ich habe Daten in Spalten, die ich Berechnungen ausführen muss. Ist es möglich, dies mit den vorherigen Zeilenwerten zu tun, ohne eine Schleife zu verwenden? Z.B. Wenn in der ersten Spalte der Wert 139 ist, berechne den Median der letzten 5 Werte und die prozentuale Änderung des Wertes 5 Zeilen darüber und den Wert in der aktuellen Zeile?Berechnung in Spalten mit vorherigen Zeile Wert ohne Schleifen

ID Data PF 
135 5  123 
136 4  141 
137 5  124 
138 6  200 
139 1  310 
140 2  141 
141 4  141 

Also hier in diesem Datensatz würden Sie tun:

  1. Finden 139 in ID Spalte
  2. Return durchschnittlich letzten 5 Zeilen in Data (Gibt 4.2)
  3. Return Performance von Werten in PF 5 Zeilen über dem aktuellen Wert (gibt 152%)

Wenn ich würde eine Schleife tun es wie folgt aussieht:

for (i in 1:nrow(data)){ 
    if(data$ID == "139" & i>=3) 
    {data$New_column <- data[i,"PF"]/data[i-4,"PF"] - 1 
} 

Das Problem ist, dass die Schleife Punkte viele Daten aufgrund zu lange dauert. Die ID 139 erscheint mehrmals im Datensatz.

Vielen Dank. Carlos

+0

Fügen Sie ein reproduzierbares Beispiel und eine erwartete Ausgabe hinzu. – Sotos

+2

Schauen Sie sich 'rollapply' im' zoo' Paket an. – Tutuchan

+0

Können Sie definieren, was Sie mit der Leistung von Werten in PF 5 Zeilen über dem aktuellen Wert meinen? Es ist gemein? Sein Median? In jedem Fall haben Sie nicht 5 Zeilen über 139 nur 4. – aichao

Antwort

0

Wollen Sie das?

ntest=139 
sol<-sapply(5:nrow(df),function(ii){#ii=6 
    tdf<-df[(ii-4):ii,] 
    if(tdf[5,1]==ntest) 
    c(row=ii,aberage=mean(tdf[,"Data"]),performance=round(100*tdf[5,"PF"]/tdf[1,"PF"]-1,0)) 
}) 
sol<- sol[ ! sapply(sol, is.null) ] #remove NULLs 
sol 

[[1]] 
     row  aberage performance 
     5.0   4.2  251.0 
0

Dies könnte ein anständiger Start sein:

mytext = "ID,Data,PF 
135,5,123 
136,4,141 
137,5,124 
138,6,200 
139,1,310 
140,2,141 
141,4,141" 

mydf <- read.table(text=mytext, header = T, sep = ",") 

do.call(rbind,lapply(mydf$ID[which(mydf$ID==139):nrow(mydf)], function(x) { 
    tempdf <- mydf[1:which(mydf$ID==x),] 
    data.frame(ID=x,Data=mean(tempdf$Data),PF=100*(tempdf[nrow(tempdf),"PF"]-tempdf[(nrow(tempdf)-4),"PF"])/tempdf[(nrow(tempdf)-4),"PF"]) 
})) 

ID  Data  PF 
139 4.200000 152.03252 
140 3.833333 0.00000 
141 3.857143 13.70968 

Die Idee dabei ist: Sie nehmen ID bis zum Ende ausgehend ‚s ab 139 und verwenden Sie die lapply Funktion auf jeden von ihnen durch eine temporäre Erzeugung data.frame, das alle Zeilen über diesem speziellen ID (einschließlich der ID selbst) enthält. Dann greifen Sie den Mittelwert der Spalte Data und die Änderungsrate (d. H. Wie Sie die Leistung nennen) der Spalte PF.

2

Wie von Tutuchacn und Sotos, verwenden Sie das Paket zoo die mean der Data in den letzten N Zeilen (einschließlich der Reihe) erhalten Sie abfragen (vorausgesetzt, Ihre Daten in den Datenrahmen df):

library(zoo) 

ind <- which(df$ID==139)        ## this is the row you are querying 
N <- 5            ## here, N is 5 
res <- rollapply(df$Data, width=N, mean)[ind-(N-1)] 
print(res) 
## [1] 4.2 

rollapply(..., mean) gibt den Roll Mittelwert der fenster~~POS=TRUNC von width=N. Beachten Sie, dass der Index, der zum Abfragen der Ausgabe von rollapply verwendet wird, um N-1 verzögert wird, weil der rollende Mittelwert in der Reihe vorwärts angewendet wird.

Um die prozentuale Leistung von PF erhalten, wie Sie angegeben:

percent.performance <- function(x) { 
    z <- zoo(x)          ## create a zoo series 
    lz <- lag(z,4)          ## create the lag version 
    return(z/lz - 1) 
} 
res <- as.numeric(percent.performance(df$PF)[ind]) 
print(res) 
## [1] 1.520325 

Hier definieren wir eine Funktion percent.performance das zurückgibt, was Sie für alle Zeilen von df wollen, für die die Berechnung Sinn macht. Wir extrahieren dann die Zeile, die wir wollen, mit ind und wandeln sie in eine Zahl um.

Hoffe, das hilft.

Verwandte Themen