2017-06-21 2 views
1

I zwei Datenrahmen haben, eine, die Messungen und einen Zeitstempel, die andere mit Meßperioden mit einer Start- und Endzeit:Spieldaten, die durch Start- und Endzeiten

txt1 <- "  v1  datetime 
23 '2016-02-14 12:00:10' 
12 '2016-02-14 12:03:10' 
21 '2016-02-14 12:50:00' 
52 '2016-02-14 13:01:10' 
53 '2016-02-14 13:05:50' 
23 '2016-02-14 13:09:25' 
95 '2016-02-14 13:20:10' 
11 '2016-02-14 13:21:00' 
64 '2016-02-14 13:25:12' 
41 '2016-02-14 13:45:34' 
14 '2016-02-14 13:53:08' 
" 

txt2 <- " mp  start  end 
1 '2016-02-14 12:00:00' '2016-02-14 12:11:00' 
2 '2016-02-14 12:58:00' '2016-02-14 13:13:00' 
3 '2016-02-14 13:22:00' '2016-02-14 14:00:00' 
" 
d1 <- read.table(textConnection(txt1), header = TRUE, 
       colClasses = c("integer", "POSIXct")) 

d2 <- read.table(textConnection(txt2), header = TRUE, 
       colClasses = c("integer", "POSIXct" ,"POSIXct")) 

Ich will die korrekte Messung zuzuordnen Zeit jede Messung (Halt unerreichte Zeilen):

"  v1  datetime  mp 
23 '2016-02-14 12:00:10' 1 
12 '2016-02-14 12:03:10' 1 
21 '2016-02-14 12:50:00' NA 
52 '2016-02-14 13:01:10' 2 
53 '2016-02-14 13:05:50' 2 
23 '2016-02-14 13:09:25' 2 
95 '2016-02-14 13:20:10' NA 
11 '2016-02-14 13:21:00' NA 
64 '2016-02-14 13:25:12' 3 
41 '2016-02-14 13:45:34' 3 
14 '2016-02-14 13:53:08' 3 
" 

Mein aktueller Ansatz ist ein verschachteltes for-Schleife zu verwenden, aber ich für eine effizientere Methode suchen.

+1

versuchen [foverlaps] (https://www.rdocumentation.org/packages/data.table/versions/1.10.4/topics/foverlaps)? –

+0

[Datum merging zwischen Bereich und einzelne Daten] (https://stackoverflow.com/questions/38379206/date-merging-between-range-and-single-dates/38380091#38380091) –

Antwort

1

Eine Basis R Ansatz mit sapply. Für jeden Wert in datetime Spalte von d1 überprüfen wir, ob es in den Bereich einer Zeile in d2 fällt. Wenn es in den Bereich any Zeile fällt, gibt es den entsprechenden mp Wert zurück oder gibt NA zurück.

d1$tmp <- sapply(d1$datetime, function(x) { 
      mtch = x >= d2$start & x <= d2$end 
      ifelse(any(mtch), d2$mp[mtch], NA) 
      }) 
d1 

# v1   datetime tmp 
#1 23 2016-02-14 12:00:10 1 
#2 12 2016-02-14 12:03:10 1 
#3 21 2016-02-14 12:50:00 NA 
#4 52 2016-02-14 13:01:10 2 
#5 53 2016-02-14 13:05:50 2 
#6 23 2016-02-14 13:09:25 2 
#7 95 2016-02-14 13:20:10 NA 
#8 11 2016-02-14 13:21:00 NA 
#9 64 2016-02-14 13:25:12 3 
#10 41 2016-02-14 13:45:34 3 
#11 14 2016-02-14 13:53:08 3 
+0

Danke, ich versuche zu wickeln Mein Kopf herum, wie die ursprüngliche Version Ihrer Lösung (vor der Bearbeitung) funktioniert, wie die 'd2 $ mp' Spalte angegeben ist – ringgord

+1

@ringgord die ursprüngliche Version funktioniert, weil Sie Werte wie 1, 2, 3 in Ihrer' mp' Spalte haben Ersetzen Sie es durch andere Werte und es würde Ihnen falsche Werte geben. Die vorherige Version gab Ihnen die Indexposition der Übereinstimmung mit 'which', wobei Sie den Wert in der Spalte' mp' benötigen, der mit dem Index übereinstimmt. –

1

Nicht sicher, ob dies der effizienteste Weg ist, aber die Art, wie ich es tun würde, ist zum ersten d2 in eine Liste zu konvertieren (wobei jede Zeile ein Listeneintrag), und dann lapply durch die Liste zuweisen die richtige mp-d1:

d1$mp <- NA 
d2_list <- split(d2, seq(nrow(d2))) 

lapply(
    d2_list, 
    function(row) d1$mp[d1$datetime >= row$start & d1$datetime <= row$end] <<- row$mp 
) 

Notiere die <<- Zuweisungsoperator in der Funktion anwenden. Sie erhalten auch einige Ausdrucke in der Konsole, die irrelevant sind, aber ds1 wird wie beabsichtigt geändert.

Verwandte Themen