2016-08-15 4 views
5

Ich habe eine Frage bezüglich data.table verweisen in R ich habe einen Datensatz wie dieseWie mehrere vorherigen Zeilen in R data.table

data <- data.table(a=c(1:7,12,32,13),b=c(1,5,6,7,8,3,2,5,1,4)) 

    a b 
1: 1 1 
2: 2 5 
3: 3 6 
4: 4 7 
5: 5 8 
6: 6 3 
7: 7 2 
8: 12 5 
9: 32 1 
10: 13 4 

Jetzt will ich eine dritte Spalte c erzeugen, die Ich werde den Wert jeder Zeile von a mit allen vorherigen Werten von b vergleichen und prüfen, ob ein Wert von b größer als a ist. Zum Beispiel ist in Zeile 5 a = 5 und der vorherige Wert von b ist 1,5,6,7. so 6 und 7 ist größer als 5, also Wert von c 1 sein sollte, sonst wäre es 0. das Ergebnis wie dies

 a b c 
1: 1 1 NA 
2: 2 5 0 
3: 3 6 1 
4: 4 7 1 
5: 5 8 1 
6: 6 3 1 
7: 7 2 1 
8: 12 5 0 
9: 32 1 0 
10: 13 4 0 

ich mit einem versuchten Schleife sein soll, aber es dauert eine sehr lange Zeit . Ich habe auch shift versucht, aber ich kann mich nicht auf mehrere vorherige Zeilen mit shift beziehen. Hat jemand eine Empfehlung?

Antwort

5
library(data.table) 
data <- data.table(a=c(1:7,12,32,13),b=c(1,5,6,7,8,3,2,5,1,4)) 
data[,c:= a <= shift(cummax(b))] 
+2

Es ist mehr ein Punkt für OP - wollen Sie wirklich etwas, das eindeutig ein logisches Objekt ist, um als eine ganze Zahl gespeichert zu werden? Ich verstehe den Instinkt, Ganzzahlen zu wollen, aber logische Spalten sollten als "logisch" gespeichert werden, wenn Sie mich fragen – MichaelChirico

2

Dies ist eine Basis R-Lösung (siehe dplyr Lösung unten):

data$c = NA 
data$c[2:nrow(data)] <- sapply(2:nrow(data), function(x) { data$c[x] <- any(data$a[x] < data$b[1:(x-1)]) }) 

##  a b c 
## 1: 1 1 NA 
## 2: 2 5 0 
## 3: 3 6 1 
## 4: 4 7 1 
## 5: 5 8 1 
## 6: 6 3 1 
## 7: 7 2 1 
## 8: 12 5 0 
## 9: 32 1 0 
## 10: 13 4 0 

EDIT

Hier ist eine einfachere Lösung mit dplyr

library(dplyr) 
### Given the cumulative max and comparing to 'a', set see to 1/0. 
data %>% mutate(c = ifelse(a < lag(cummax(b)), 1, 0)) 

##  a b c 
## 1 1 1 NA 
## 2 2 5 0 
## 3 3 6 1 
## 4 4 7 1 
## 5 5 8 1 
## 6 6 3 1 
## 7 7 2 1 
## 8 12 5 0 
## 9 32 1 0 
## 10 13 4 0 

### Using 'shift' with dplyr 
data %>% mutate(c = ifelse(a <= shift(cummax(b)), 1, 0)) 
+0

Sie vielleicht kann dieses 'data%>% muate (c = as.integer (a Sumedh

+0

Eine Sache zu beachten ist, dass Ihre erste Lösung eine Basis-Dataframe-Lösung ist, die die Effizienz von data.table nicht nutzt. –

+0

@DeanMacGregor Danke für den Vorschlag, es wird eine Weile dauern, bis ich eine 'data.table' Lösung gefunden habe, da ich' dplyr' besser kenne. – steveb

Verwandte Themen