2017-02-14 3 views
2

Sagen wir, wir müssen fortlaufende Nummer größer als 40 aber gruppenweise (Tag) so zählen, dass das Zählen der fortlaufenden Nummer unabhängig von Tag sein soll.Zählen Sie die Anzahl der aufeinander folgenden nicht größer als Schwellenwert, sondern gruppenweise in einem gegebenen Datenrahmen

Zum Beispiel haben wir 6 Gruppe von Tag-Spalte so für jede Gruppe werden wir berechnen, wie oft Temp-Variable Threshold-Wert überschritten hat. Unten ist reproduzierbar Beispiel Ich versuchte zu präsentieren, mit diesem fügte ich einen Snap der erwarteten Ausgabe.

tag<- c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 
     3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5,5, 5, 
     6, 6, 6, 6, 6, 6, 6, 6, 6, 6) 
temp<- c(43, 44, 45, 41, 43, 38, 40, 41, 39, 37, 37, 39, 45, 42, 41, 43, 44, 39,38, 
     37, 43, 44, 45, 41, 43, 38, 40, 41, 39, 37, 37, 39, 45, 42, 41, 43, 44, 
     39, 38, 37, 43, 44, 45, 41, 43, 38, 40, 41, 39, 37, 37, 39, 45, 42, 41,43, 
     44, 39, 38, 37) 

df=data.frame(tag=tag,temp=temp) 

Erwartete Ausgabe ist die dritte Spalte Status

enter image description here

+0

Ich denke, es gibt einen Tippfehler. Ihre dritte Gruppe sollte bei Sr beginnen. No: 21 – akrun

+0

@akrun Ja, es ist ein Tippfehler, ich stimme dem zu. Herr, bitte, können Sie den Code erklären, der wirklich hilfreich wäre –

Antwort

2

Wir data.table verwenden können. Konvertieren Sie 'data.frame' in 'data.table' (setDT(df)), erstellen Sie eine Gruppierungsvariable mit der Lauflängen-ID des logischen Vektors (temp >= 40), gruppiert mit 'tag', 'grp' und setzen Sie die i mit logische Bedingung, ordnen wir 'Status' als Folge von Reihen (seq_len(.N)), und wandeln die 'NA' Elemente in 'Status' zu 0

library(data.table) 
setDT(df)[, grp := rleid(temp >= 40)][temp >= 40, status := seq_len(.N) , .(tag, grp) 
      ][is.na(status), status := 0][] 
head(df, 20)  
# tag temp grp status 
# 1: 1 43 1  1 
# 2: 1 44 1  2 
# 3: 1 45 1  3 
# 4: 1 41 1  4 
# 5: 1 43 1  5 
# 6: 1 38 2  0 
# 7: 1 40 3  1 
# 8: 1 41 3  2 
# 9: 1 39 4  0 
#10: 1 37 4  0 
#11: 2 37 4  0 
#12: 2 39 4  0 
#13: 2 45 5  1 
#14: 2 42 5  2 
#15: 2 41 5  3 
#16: 2 43 5  4 
#17: 2 44 5  5 
#18: 2 39 6  0 
#19: 2 38 6  0 
#20: 2 37 6  0 

Oder rle von base R verwenden. Wir verwenden ave, um nach "tag" zu gruppieren, erhalten die rle des logischen Vektors (temp >=40), replizieren die values durch die lengths und multiplizieren sie mit der sequence von lengths. Die TRUE/FALSE Werte werden zu 1/0 erzwungen und wenn eine Zahl mit 1 multipliziert wird, gibt sie diese Zahl zurück, während mit 0 der 0 Wert erhalten wird.

df$status <- with(df, ave(temp >= 40, tag, FUN = function(x) { 
      rl <- rle(x) 
      with(rl, sequence(lengths) * rep(values, lengths))})) 
df$status 
#[1] 1 2 3 4 5 0 1 2 0 0 0 0 1 2 3 4 5 0 0 0 1 2 3 4 5 
#[26] 0 1 2 0 0 0 0 1 2 3 4 5 0 0 0 1 2 3 4 5 0 1 2 0 0 0 0 1 2 3 4 5 0 0 0 
Verwandte Themen