2016-06-17 5 views
2

Ich bin ziemlich neu in R und weiß nicht, ob diese Frage dumm ist oder nicht, aber ich habe das folgende Problem: Ich habe zwei Datenrahmen, die beide einen Zeitstempel enthalten Spalte (Posixct). Ich möchte die Daten wie folgt unterteilen: Die neue df3 enthält alle Spalten von df1, bedingt durch das Auftreten des Wertes "21" in der Spalte "State" in df2. Wenn dies eintritt, müssen alle Beobachtungen von df1 von 2 Stunden vor bis 1 Stunde nach dem Auftreten des Zustands 21 in df2 in der neuen df3 sein.Subsetting ein Datenrahmen führt zu einem unerwarteten Verhalten

Hier sind zwei Beispiele meiner ursprünglichen Datenrahmen.

df2:

timestamp   PlantNo State 
37 2016-03-14 08:53:25  1  2 
38 2016-03-14 09:31:43  1  0 
39 2016-03-14 09:34:43  1  0 
40 2016-03-14 13:49:18  1  2 
41 2016-03-14 14:17:42  1  0 
42 2016-03-14 14:20:41  1  0 
43 2016-03-17 01:54:07  1  2 
44 2016-03-17 07:06:23  1  0 
45 2016-03-17 07:09:23  1  0 
46 2016-03-17 10:10:11  1 21 
47 2016-03-17 10:46:29  1  2 

df1:

 timestamp  PlantNo Error avws maxws minws avrot maxrot minrot avpwr 
1 2016-03-05 00:00:00  1  0 6.7 9.3 4.3 25.15 30.96 21.37 93 
2 2016-03-05 00:10:00  1  0 7.9 11.1 5.5 29.05 34.26 22.89 145 
3 2016-03-05 00:20:00  1  0 7.8 10.5 4.6 28.83 33.17 23.34 142 
4 2016-03-05 00:30:00  1  0 7.8 10.4 5.3 28.91 33.94 24.09 142 
5 2016-03-05 00:40:00  1  0 7.9 10.1 5.4 28.36 32.89 23.03 134 
6 2016-03-05 00:50:00  1  0 7.8 9.2 5.4 27.83 31.41 22.48 126 
7 2016-03-05 01:00:00  1  0 7.8 9.0 6.6 28.06 30.21 25.87 129 
8 2016-03-05 01:10:00  1  0 7.2 9.0 4.7 24.91 29.23 9.92 91 
9 2016-03-05 01:20:00  1  0 7.0 8.7 3.9 25.04 28.53 20.39 92 
10 2016-03-05 01:30:00  1  0 7.2 9.1 3.7 26.04 30.39 20.75 103 
11 2016-03-05 01:40:00  1  0 7.5 9.3 5.1 26.75 30.98 21.80 111 
12 2016-03-05 01:50:01  1  0 7.5 8.7 4.9 26.94 28.96 22.46 114 
13 2016-03-05 02:00:00  1  0 7.1 9.0 4.4 25.32 30.24 20.38 95 
14 2016-03-05 02:10:00  1  0 7.5 9.0 5.0 26.47 29.35 22.85 108 
15 2016-03-05 02:20:00  1  0 7.3 9.1 4.2 26.03 30.97 19.43 104 
16 2016-03-05 02:30:00  1  0 6.7 10.1 3.9 24.66 30.98 20.06 88 
17 2016-03-05 02:40:00  1  0 6.8 9.1 4.5 25.30 30.22 20.88 94 
18 2016-03-05 02:50:00  1  0 7.2 10.1 4.2 25.95 31.17 20.74 103 
19 2016-03-05 03:00:00  1  0 7.6 10.3 4.3 27.72 34.43 22.19 127 
20 2016-03-05 03:10:00  1  0 8.7 12.2 5.3 31.42 35.69 25.32 189 

Ich habe versucht, den folgenden Code:

df3 <- subset(df1, df1$timestamp > df2$timestamp[df2$State==21]-7200 & 
        df1$timestamp < df2$timestamp[df2$State==21]+3600) 

Im Grunde ist dies für mich funktioniert, wie die richtigen Zeitrahmen ausgewählt und gespeichert werden in df3, aber: nur jede vierte Beobachtung von df1 geht in df3. Dies ist, was ich am Ende bekommen:

  timestamp  PlantNo Error avws maxws minws avrot maxrot minrot avpwr 
1781 2016-03-17 08:30:00  1  0 2.2 2.7 1.6 14.57 15.85 13.52  0 
1785 2016-03-17 09:10:00  1  0 1.7 2.4 0.7 10.43 13.48 8.71  0 
1789 2016-03-17 09:50:00  1  0 1.9 2.9 0.7 11.62 15.91 6.86  0 
1793 2016-03-17 10:30:00  1  0 2.4 4.3 0.6 0.27 1.59 0.00  0 
1797 2016-03-17 11:10:00  1  0 2.7 4.2 1.7 16.38 18.76 13.17  0 
3006 2016-03-25 22:40:00  1  0 5.4 6.9 4.1 19.99 21.95 19.21 41 
3010 2016-03-25 23:20:00  1  0 6.0 7.1 4.6 21.43 24.59 19.59 56 
3014 2016-03-26 00:00:00  1  0 5.1 6.5 4.0 19.41 20.33 18.90 30 
3018 2016-03-26 00:40:00  1  0 5.2 6.6 3.0 4.06 20.82 0.00  4 
3022 2016-03-26 01:20:00  1  0 5.2 6.4 3.7 19.52 20.26 18.75 33 
3583 2016-03-29 23:40:00  1  0 5.7 6.8 4.9 20.57 22.80 19.60 48 
3587 2016-03-30 00:20:00  1  0 6.4 7.5 5.4 22.82 25.10 20.27 68 
3591 2016-03-30 01:00:00  1  0 6.1 7.4 5.2 21.94 23.99 20.52 60 
3595 2016-03-30 01:40:00  1  0 4.0 5.0 2.4 2.90 18.99 0.00  1 
3599 2016-03-30 02:20:00  1  0 5.4 6.2 4.5 19.63 20.05 19.26 36 
3812 2016-03-31 13:50:00  1  0 2.2 4.3 0.8 13.95 18.30 7.89  1 
3816 2016-03-31 14:30:00  1  0 0.8 2.1 0.0 0.00 0.10 0.00  0 
3820 2016-03-31 15:10:00  1  0 0.6 1.4 0.0 0.00 0.00 0.00  0 
3824 2016-03-31 15:50:00  1  0 2.5 4.4 0.6 11.54 19.12 0.00  1 
3828 2016-03-31 16:30:00  1  0 2.8 4.3 1.7 5.31 18.39 0.00  1 

Die linken Spalten ist die Anzahl der Beobachtung in df1. Kann mir jemand sagen, was ich falsch mache?

+0

Ich denke, dass eine Stichprobe von Originaldaten mit der erwarteten Ausgabe einfacher zu lesen wäre als das, was Sie uns gegeben haben. –

+1

Erwägen Sie, in Ihrem Beitrag die ersten 10 Zeilen von 'df1' und' df2' mit nicht relevanten Spalten zu berücksichtigen. –

+0

Hilft Ihnen das? –

Antwort

1

Vielleicht ist Ihr Vergleich df1$timestamp>(df2$timestamp[df2$State==21]-7200) recycling. Dies ist der Fall, wenn df2$State==21 mehr als einen Fall zurückgibt.

Versuchen Sie Folgendes, da wir nicht genügend Daten haben Ich bin mir nicht sicher, ob es für Sie funktioniert.

inf=df2$timestamp[df2$State==21]-7200 
sup=df2$timestamp[df2$State==21]+3600 

trs=list() 
for (i in 1:length(inf))trs[[i]]=df1$timestamp>inf[i] & df1$timestamp<sup[i] 
selv=apply(t(do.call("rbind",trs)),1,any) 
df31 <- subset(df1,selv) 
+0

Ich denke auch, dass das Recycling das Problem ist, dass eine Teilmenge nicht funktioniert. – Alex

+0

Vielen Dank. Das hat mein Problem gelöst. –

0

Nur eine Vermutung: Vielleicht brauchen Sie subset(df1, df1$timestamp > (df2$timestamp[df2$State==21]-7200) & df1$timestamp < (df2$timestamp[df2$State==21]+3600))?

0

Ich bin mir nicht sicher, ob ich zu kompliziert denke, aber meiner Meinung nach sollte Subset nicht so leicht funktionieren.

Ich baute ein Beispiel für zwei data.frames mit zwei zufälligen Zeitstempeln, die im gleichen Bereich liegen. Ich habe eine hässliche verschachtelte for-Schleife verwendet, um zu überprüfen, ob jeder der Zeitstempel in df2 im Bereich von + - 1 Stunde aller Zeitstempel mit state = 1 von df1 liegt. Wenn ja, wird state = 1 zu df2 hinzugefügt. Für das gewünschte Ergebnis können Sie einfach df2 unterteilen.

set.seed(1) 
t1 <- sort(as.POSIXct(sample(1:10000000, 1000) ,origin = "2010-01-01")) 
state <- sample(0:1,10000, replace = TRUE, prob = c(0.90,0.05)) 
df1 <- data.frame(t1, state) 

t2 <- sort(as.POSIXct(sample(1:10000000, 1000) ,origin = "2010-01-01")) 
df2 <- data.frame(t2, ID = 1:length(t2)) 

df1_h <- df1[df1$state == 1, ] 

df2$state <- NA 
for (i in 1:nrow(df2)){ 
    for(j in 1:nrow(df1_h)){ 
    if(df2$t2[i] > df1_h$t1[j] - 3600 & df2$t2[i] < df1_h$t1[j] + 3600) df2$state[i] <- 1 
    } 
} 

df3 <- df2[df2$state == 1, ] 
Verwandte Themen