2016-12-20 3 views
2

Ich möchte die ersten Zeilen eines Datenrahmens unter der Bedingung auswählen, dass die Summe der Werte einer Spalte größer als eine bestimmte Zahl ist . Nehmen Sie zum Beispiel die Datenautos. Angenommen, ich möchte Zeilen basierend auf Werten in der zweiten Spalte auswählen. Wenn meine Nummer 7 ist, werden die erste und die zweite Zeile ausgewählt, die Werte in der zweiten Spalte für die ersten zwei Zeilen sind (2 + 10)> 7); Wenn die Anzahl 34 ist, werden die ersten 4 Zeilen ausgewählt werden, (2 + 10 + 4 + 22> 34)Funktion zum Zurückgeben der ersten Zeilen, in denen die Summe der Spaltenwerte größer als eine Zahl ist. R

habe ich versucht, die folgende, die das alle Zeilen unabhängig von dem Eingabewert

foo<-function (z) { 
    for (i in 1: nrow (cars)) { 
    if(sum(cars[i,2])<z) { 
    sum(cars[1:i,2]) 
    } else { 
    return (cars[1:i,]) 
    } 
    } 
    return (cars[1:i,]) 
} 

I kehrt versuchte auch unter Verwendung while, aber endete mit nur dem ersten Wert, der endlos zurückgebracht wurde. wäre viel besser

+0

i 'cumsum' denken gemacht werden. Bitte teilen Sie eine Probe Daten und auch die erwartete Leistung auf der Grundlage dieser Probe –

+0

Verwenden Sie 'Cumsum ', fügen Sie eine weitere Spalte als Cumsum, dann wählen Sie basierend auf dieser – jf328

Antwort

2

Wir können ein cumsum mit which

cars[seq(which.max(cumsum(cars$dist)>34)),] 

tun, und dies kann in eine Funktion

f1 <- function(dat, col, thresh){ 
     dat[seq(which.max(cumsum(dat[[col]])> thresh)),] 
} 

f1(cars, "dist", 34) 
# speed dist 
#1  4 2 
#2  4 10 
#3  7 4 
#4  7 22 

f1(cars, "dist", 7) 
# speed dist 
#1  4 2 
#2  4 10 
+2

Guess' seq_len (findInterval (Thresh, Cumsum (Autos $ dist)) + 1) 'könnte effizienter sein. – nicola

+0

@nicola Danke, ich habe gerade mit 'findInterval' getestet, aber ich habe den' cumsum' Teil nicht benutzt, danke dafür. Da dies eine andere Option ist, wäre es besser, Sie als Antwort zu posten. – akrun

Verwandte Themen