2017-07-28 3 views
1

Ich verstehe, dass die Frage etwas verwirrend scheint. Ein Beispiel könnte sein,R Wie erhält man den Unterschied zwischen der aktuellen und der nächsten Zeile, die bestimmten Bedingungen entspricht?

      Time  x 
    2017-07-24 12:33:13.000000  0.0 
    2017-07-24 12:33:14.000000  0.0 
    2017-07-24 12:33:15.000000  0.0 
    2017-07-24 12:33:16.000000  0.0 
    2017-07-24 12:33:16.500000  1.0 
    2017-07-24 12:33:17.000000  0.0 
    2017-07-24 12:33:17.500000  0.0 
    2017-07-24 12:33:18.500000  1.0 

In R, ich will eine andere Spalte haben, das für jede Zeile, Rechen Differenz zwischen der Zeit für die aktuelle Zeile und die Zeit für die nächste Zeile, wobei x nicht 0, so dass Die Ergebnisse sehen so aus:

      Time  x  diff 
    2017-07-24 12:33:13.000000  0.0  3.5 
    2017-07-24 12:33:14.000000  0.0  2.5 
    2017-07-24 12:33:15.000000  0.0  1.5 
    2017-07-24 12:33:16.000000  0.0  0.5 
    2017-07-24 12:33:16.500000  1.0  0.0 
    2017-07-24 12:33:17.000000  0.0  1.5 
    2017-07-24 12:33:17.500000  0.0  1.0 
    2017-07-24 12:33:18.500000  1.0  0.0 

Vielen Dank für Ihre Antwort im Voraus.

Antwort

2

die Zeilen zu finden, wo "x == 1":

wh = which(dat$x == 1) 

können wir einen Vektor von Indizes der nächsten bauen (vorwärts) "1":

i = rep(wh, c(wh[1], diff(wh))) 

Und dann die jeweiligen "Time" s subtrahieren:

dat$Time[i] - dat$Time 
#Time differences in secs 
#[1] 3.5 2.5 1.5 0.5 0.0 1.5 1.0 0.0 

"dat" ist:

dat = structure(list(Time = structure(c(1500888793, 1500888794, 1500888795, 
1500888796, 1500888796.5, 1500888797, 1500888797.5, 1500888798.5 
), class = c("POSIXct", "POSIXt"), tzone = ""), x = c(0, 0, 0, 
0, 1, 0, 0, 1)), .Names = c("Time", "x"), row.names = c(NA, 8L 
), class = "data.frame") 
3

Ich denke, ein Rolling join aus der data.table() Bibliothek kann helfen.

Hier ist meine Lösung:

Lassen Sie uns zunächst Ihre Beispieldaten einrichten

library('data.table') 

time <- as.POSIXct(c('2017-07-24 12:33:13.000000', '2017-07-24 12:33:14.000000', '2017-07-24 12:33:15.000000', '2017-07-24 12:33:16.000000', '2017-07-24 12:33:16.500000', '2017-07-24 12:33:17.000000', '2017-07-24 12:33:17.500000', '2017-07-24 12:33:18.500000')) 

x <- c(0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0) 

dat <- data.table(time, x) 

Jetzt wollen wir eine Dummy-Spalte im Interesse der Join hinzufügen:

dat[, key := 1] 

Subset der Daten zu nur den x = 1 Spalten in eine neue Tabelle

ones <- dat[x==1, list(time, key, ref.time = time)] 

Beachten Sie, dass ich auch eine ref.time Spalte erstellen. Das ist für die Durchführung der Subtraktion.

Set Schlüssel für den Roll beitreten

setkey(dat, key, time) 
setkey(ones, key, time) 

Nun ist die beitreten kann. Dies beantwortet die Frage "Was ist die nächste x == 1 Zeile zu jeder gegebenen Zeile in den ursprünglichen Daten"

joined.dat <- ones[dat, roll = -Inf] 

Compute der Unterschied, den Sie suchen

joined.dat[, diff := ref.time - time] 

fertige Ausgabe:

    time key   ref.time x  diff 
1: 2017-07-24 12:33:13 1 2017-07-24 12:33:16 0 3.5 secs 
2: 2017-07-24 12:33:14 1 2017-07-24 12:33:16 0 2.5 secs 
3: 2017-07-24 12:33:15 1 2017-07-24 12:33:16 0 1.5 secs 
4: 2017-07-24 12:33:16 1 2017-07-24 12:33:16 0 0.5 secs 
5: 2017-07-24 12:33:16 1 2017-07-24 12:33:16 1 0.0 secs 
6: 2017-07-24 12:33:17 1 2017-07-24 12:33:18 0 1.5 secs 
7: 2017-07-24 12:33:17 1 2017-07-24 12:33:18 0 1.0 secs 
8: 2017-07-24 12:33:18 1 2017-07-24 12:33:18 1 0.0 secs 
+0

Ihre Antwort kann etwas sauberer sein, wenn Sie verwenden 'dplyr' oder' tidyverse' oder verwenden 'data.table' effizienter. Aber ich mag die Idee. Prost. +1 – Masoud

+0

Danke für die Upvote und Feedback! Gibt es irgendwelche besonderen Gründe, warum die Verwendung der data.tables effizienter sein könnte? Das war ein bisschen beschwerlich, als ich es zusammenstellte, aber ich war mir nicht sicher, wie ich es rationalisieren sollte. – HarlandMason

0

Base anhand von R und Vektorisierung:

a <- c(1, 3, 6, 10, 15, 17, 20, 23, 34) 
b <- c(0, 0, 0, 1, 0, 1, 0, 0, 1) 

Von Hand, sollte die Antwort sein:

c <- c(9, 7, 4, 0, 2, 0, 14, 11, 0) 

einen Vektor von dem in b-Werte erstellen sind die ‚schwenkt‘.Wir legen auch 0 als Ausgangspunkt:

pivots <- c(0, which(b != 0)) 

schließlich jene schwenken beliebig oft wiederholen sind, gibt es zwischen einem Wert von 0 und den nächsten 1.

vec <- rep(a[pivots], times = diff(pivots) 
identical(c, vec - a) 

Wenn Sie wollten diese in eine Funktion aktivieren, die eine values Vektor/Spalte und Sie pivots Vektor/Spalte nimmt so etwas tun kann:

diffToNextPivot <- function(values, pivots) { 
    pivots <- c(0, which(pivots != 0)) 
    vec <- rep(values[pivots], times = diff(pivots)) 
    vec - values 
} 

myDataFrame$diff <- diffToNextPivot(myDataFrame$Time, myDataFrame$x) 
Verwandte Themen