2017-09-30 2 views
0

Ich habe viel gesucht für diese einfache Frage, aber habe keine Lösung gefunden. Es sieht wirklich einfach aus. Ich habe einen Datenrahmen mit einer Säule wie folgt aus:Zuweisen von Gruppen basierend auf dem Trend

Value 
0.13 
0.35 
0.62 
0.97 
0.24 
0.59 
0.92 
0.16 
0.29 
0.62 
0.98 

Alle Werte haben einen Bereich zwischen 0 und 1. Was ich will, ist, dass, wenn der Wert beginnt zu fallen, ich eine neue Gruppe zuweisen. Innerhalb jeder Gruppe steigt der Wert. So wird das ideale Ergebnis wie folgt aussehen:

Value Group 
0.13 1 
0.35 1 
0.62 1 
0.97 1 
0.24 2 
0.59 2 
0.92 2 
0.16 3 
0.29 3 
0.62 3 
0.98 3 

Hat jemand einen Vorschlag, wie man das anspricht?

Antwort

2

Dies ist nicht die eleganteste Lösung, aber es funktioniert:

value <- c(0.13, 0.35, 0.62, 0.97, 0.24, 0.59, 0.92, 0.16, 0.29, 0.62, 0.98) 

foo <- data.frame(value, group = 1) 
current_group <- 1 
for(i in 2:nrow(foo)){ 
    if(foo$value[i] >= foo$value[i-1]){ 
    foo$group[i] <- current_group 
    }else{ 
    current_group <- current_group + 1 
    foo$group[i] <- current_group 
    } 
} 
+0

Dieses if-else geht zurück auf die essentielle Logik und es funktioniert für meinen komplexen Datensatz. Viel besser als Funktionen in Paketen zu verwenden. Vielen Dank, Brendan! –

2


df <- data.frame(x = c(0.13, 0.35, 0.62, 0.97, 0.24, 0.59, 0.92, 0.16, 0.29, 0.62, 0.98)) 
df$y <- c(df$x[-1], NA) # lag column 
df$chgdir <- as.numeric(df$y - df$x < 0) # test for change in direction 
df$chgdir[is.na(df$chgdir)] <- 0 # deal with NA 
df$group <- cumsum(df$chgdir) + 1 # determine group number 
df[,c("x", "group")] 
#>  x group 
#> 1 0.13  1 
#> 2 0.35  1 
#> 3 0.62  1 
#> 4 0.97  2 
#> 5 0.24  2 
#> 6 0.59  2 
#> 7 0.92  3 
#> 8 0.16  3 
#> 9 0.29  3 
#> 10 0.62  3 
#> 11 0.98  3 
+0

Sehr schöne Lösung! Cumsum funktioniert definitiv! Vielen Dank Alter! –

3

Diese den Trick tun sollten, und verwendet nur vektorisiert Basisfunktionen. Vielleicht möchten Sie die < für <= austauschen, wenn dies das gewünschte Verhalten ist.

vec <- c(0.13, 0.35, 0.62, 0.97, 0.24, 0.59, 0.92, 0.16, 0.29, 0.62, 0.98) 

cumsum(c(1, diff(vec) < 0)) 
+0

Dies ist eine viel bessere Lösung als mein Vorschlag und wird schneller sein, wenn der Wertvektor groß ist. –

Verwandte Themen