2016-07-21 7 views
1

Ich habe dieses Beispiel:Regular Zeit zwischen den Reihen mit R

structure(list(timestamp_pretty = structure(c(1L, 3L, 4L, 5L, 
6L, 7L, 8L, 9L, 10L, 12L, 13L, 14L, 17L, 18L, 20L, 2L, 11L, 15L, 
16L, 19L), .Label = c("01/06/2014 00:04:00", "01/06/2014 00:04:01", 
"01/06/2014 00:07:10", "01/06/2014 00:10:10", "01/06/2014 00:13:11", 
"01/06/2014 00:19:20", "01/06/2014 00:20:02", "01/06/2014 00:22:20", 
"01/06/2014 00:25:30", "01/06/2014 01:11:11", "01/06/2014 01:16:03", 
"01/06/2014 01:17:12", "01/06/2014 01:20:41", "01/06/2014 01:26:51", 
"01/06/2014 01:28:03", "01/06/2014 01:43:03", "01/06/2014 01:45:20", 
"01/06/2014 02:12:01", "01/06/2014 02:13:05", "01/06/2014 02:18:01" 
), class = "factor"), mmsi = c(205477000L, 205477000L, 205477000L, 
205477000L, 205477000L, 205477000L, 205477000L, 205477000L, 205477000L, 
205477000L, 205477000L, 205477000L, 205477000L, 205477000L, 205477000L, 
205482000L, 205482000L, 205482000L, 205482000L, 205482000L)), .Names = c("timestamp_pretty", 
"mmsi"), row.names = c(8L, 9L, 17L, 16L, 4L, 12L, 3L, 14L, 10L, 
7L, 13L, 19L, 6L, 15L, 1L, 11L, 18L, 20L, 2L, 5L), class = "data.frame") 

die Säule diff_time_seconds_timestamp_pretty ist die Zeitdifferenz zwischen den Reihen von mmsi.

Ich möchte einige Signale (Zeilen) entfernen und nur die Signale alle XXX Sekunden (zum Beispiel 180 Sekunden) für jede mmsi halten.

Mein Gedanke war, das Paket zoo zu verwenden, scheint es dafür getan zu werden. Aber ich konnte es nicht schaffen, so jetzt ich bin auf der Suche nach:

  1. Fügen Sie die cum Summe der diff_time_seconds_timestamp_pretty pro MMSI
  2. , um die Signale zu entfernen, die weniger als 180 Sekunden von einander.
  3. Um die Signale zu halten, die mindestens 180 Sekunden von eachother

Ich versuche mit

library(dplyr) 
test <- data %>% 
    group_by(mmsi) %>% 
    mutate(cum.sum=cumsum(diff_time_seconds_timestamp_pretty)) 

zu arbeiten, aber es scheint, dass ich bin noch weit davon entfernt, was ich will.

Hilfe ist willkommen!

+0

können Sie Ihre erwartete Ausgabe hinzufügen? Etwas wie 'df%>% group_by (mmsi)%>% muate (diff_time = timestamp_pretty - lag (timestamp_pretty))%>% filter (diff_time> = 180)' würde funktionieren? – Sotos

+0

Das könnte funktionieren. Ich werde weiterhin mit dieser Basis arbeiten, danke. Die Ausgabe ist ein bisschen schwierig zu produzieren. Ich weiß nur, dass die meisten Signale alle 10 Sekunden sind, und ich möchte nur Signale alle 3 oder 4 Minuten haben. – Floni

+0

Die Sache mit dieser Lösung ist, dass es auch die allererste Beobachtung eliminiert, die behoben werden kann, aber cum sum ist hier am verwirrendsten. Beachten Sie auch, dass ich 'timestamp_pretty' in' POSIXct' konvertiert habe, dh 'df $ timestamp_pretty <- as.POSIXct (df $ timestamp_pretty, Format = '% d /% m /% Y% H:% M:% S')' – Sotos

Antwort

3

Hier sind zwei Ansätze, die die Datumsangaben in 180-Sekunden-Intervalle aufteilen und dann nur den jeweils letzten Datenpunkt behalten.

1) chron/zoo Konvertieren Sie die Zeitstempel in chron und verwenden Sie trunc.times aus diesem Paket, um sie alle 180 Sekunden (d. H. Alle 3 Minuten) zu kürzen. Dann las sie in Zoo Aggregieren zu gleichen Datum/Zeit mit der tail Funktion, so dass nur die letzten beibehalten wird:

library(chron) 
library(zoo) 
# return the chron date time at start of 180 sec interval each point is in 
to180ch <- function(x) trunc(as.chron(as.character(x), "%m/%d/%Y %H:%M:%S"), "00:03:00") 
read.zoo(data, FUN = to180ch, aggregate = function(x) tail(x, 1)) 

Das Ergebnis ist das folgende Zoo-Objekt, die chron Datum/Zeit verwendet:

(01/06/14 00:03:00) (01/06/14 00:06:00) (01/06/14 00:09:00) (01/06/14 00:12:00) 
      205482000   205477000   205477000   205477000 
(01/06/14 00:18:00) (01/06/14 00:21:00) (01/06/14 00:24:00) (01/06/14 01:09:00) 
      205477000   205477000   205477000   205477000 
(01/06/14 01:15:00) (01/06/14 01:18:00) (01/06/14 01:24:00) (01/06/14 01:27:00) 
      205482000   205477000   205477000   205482000 
(01/06/14 01:42:00) (01/06/14 01:45:00) (01/06/14 02:12:00) (01/06/14 02:18:00) 
      205482000   205477000   205482000   205477000 

Wenn das, was bevorzugt wird, ist nur den Datenrahmen Teilmenge bis zu 180 Sekunden Intervalle dann versuchen, diese:

subset(data, !duplicated(to180ch(timestamp_pretty), fromLast = TRUE)) 

2) Keine Pakete Konvertieren Sie in POSIXct und dann numerisch, führen Sie die Kürzung durch und konvertieren Sie sie zurück nach POSIXct. Schließlich aggregate mit tail:

# return the POSIXct date time at start of 180 sec interval each point is in 
to180ct <- function(x) { 
    p <- as.POSIXct(as.character(x), format = "%m/%d/%Y %H:%M:%S") 
    as.POSIXct(180 * as.numeric(p) %/% 180, origin = "1970-01-01") 
} 
aggregate(data[2], list(timestamp = to180ct(data[[1]])), tail, 1) 

gibt diesen Datenrahmen mit einem POSIXct timestamp:

   timestamp  mmsi 
1 2014-01-06 00:03:00 205482000 
2 2014-01-06 00:06:00 205477000 
3 2014-01-06 00:09:00 205477000 
4 2014-01-06 00:12:00 205477000 
5 2014-01-06 00:18:00 205477000 
6 2014-01-06 00:21:00 205477000 
7 2014-01-06 00:24:00 205477000 
8 2014-01-06 01:09:00 205477000 
9 2014-01-06 01:15:00 205482000 
10 2014-01-06 01:18:00 205477000 
11 2014-01-06 01:24:00 205477000 
12 2014-01-06 01:27:00 205482000 
13 2014-01-06 01:42:00 205482000 
14 2014-01-06 01:45:00 205477000 
15 2014-01-06 02:12:00 205482000 
16 2014-01-06 02:18:00 205477000 

Wie in (1) wenn das, was gesucht wird nur den Datenrahmen der Teilmenge dann ersetzen Sie einfach to180ch in der subset Linie in (1) mit to180ct wie folgt aus:

subset(data, !duplicated(to180ct(timestamp_pretty), fromLast = TRUE)) 
+0

Sehr gute Lösungen. Ich fand heraus, dass die Ergebnisse zwischen den beiden Lösungen unterschiedlich sind. Manchmal ist das Intervall etwas weniger als 3 Minuten, aber es könnte für mich hier genug sein, ich möchte nur zusätzliche Zeilen entfernen ... Welche Lösungen ist die beste für Sie? Ich werde an einer größeren Probe testen, um sicherzustellen, dass sie meine Daten nicht ändert (ich habe mehrere andere Spalten ...) und ich werde hier wiederkommen! Ich muss auch ein bisschen bearbeiten, damit es für jede mmsi funktioniert – Floni

+0

und ich füge hinzu, um das Datumsformat zu ändern '% m /% d /% Y% H:% M:% S 'bis'% d /% m /% Y% H:% M:% S' – Floni

+0

meinst du die Schleife 'für (i in Ebenen (Daten $ mmsi)) { read.zoo (Daten, FUN = to180ch, Aggregat = Funktion (x) Schwanz (x, 1))} test <- Teilmenge (data,! Duplicated (to180ch (timestamp_pretty) fromLast = TRUE)) test <- test [order (test $ mmsi, test $ timestamp_pretty),] gibt ein gutes Ergebnis für jeden 'mmsi' Level? Ich habe versucht, Ihre Lösung 1 für jeden mmsi anstatt für den ganzen Tisch zu laufen, aber ich konnte die Lösung nicht finden ... – Floni

Verwandte Themen