2016-04-26 9 views
1

Ich habe eine binäre Matrix, die angibt, ob eine Person (ID) zur Verfügung steht, um eine Aufgabe zu erledigen. Die beispielhafte Matrix istSuche nach allen zu einer bestimmten Zeit verfügbaren IDs

08:00 08:30 09:00 09:30 10:00 10:30 11:00 11:30 12:00 12:30 13:00 13:30 14:00 14:30 15:00 15:30 16:00 16:30 17:00 17:30 18:00 18:30 19:00 
1  1  1  1  1  1  0  1  1  1  1  0  1  1  1  1  1  1  1  0  0  0  0  0 
2  1  1  1  1  1  0  1  1  1  1  0  1  1  1  1  1  1  1  0  0  0  0  0 
3  0  1  1  1  1  1  0  1  1  1  1  0  1  1  1  1  1  1  1  0  0  0  0 
4  0  1  1  1  1  1  0  1  1  1  1  0  1  1  1  1  1  1  1  0  0  0  0 
5  0  0  1  1  1  1  1  0  1  1  1  1  0  1  1  1  1  1  1  1  0  0  0 
6  0  0  1  1  1  1  1  0  1  1  1  1  0  1  1  1  1  1  1  1  0  0  0 
    19:30 
1  0 
2  0 
3  0 
4  0 
5  0 
6  0 

Die Zeilennamen repräsentieren die IDs und die Zeit zeigte, sind die, in denen die IDs verfügbar sind. Im Beispiel beginnen die IDs 1 und 2 um 8:00 Uhr und haben bestimmte Pausenzeiten um 10: 30-11: 00, 13: 00- 13:30. Die Personen, die eine halbe Stunde später 3 und 4 beginnen, machen Pause von 11: 00-11: 30, 13: 30-14: 00. Dies stellt sicher, dass jemand für einen Job verfügbar ist, der an einem bestimmten Punkt beginnen kann.

dput (Matrix)

structure(c(1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 
0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0), .Dim = c(6L, 24L), .Dimnames = list(c("1", "2", "3", "4", 
"5", "6"), c("08:00", "08:30", "09:00", "09:30", "10:00", "10:30", 
"11:00", "11:30", "12:00", "12:30", "13:00", "13:30", "14:00", 
"14:30", "15:00", "15:30", "16:00", "16:30", "17:00", "17:30", 
"18:00", "18:30", "19:00", "19:30"))) 

andere Datenmengen hat die "IDs" mit ihrer Startzeit

data1 <- data.frame(ID = 1:6, Start_Time = c("8:00", "8:00", "8:30", 
      "8:30", "9:00", "9:30"), stringsAsFactors=FALSE) 

Ein dritte Datensatz die Start- und Endzeitpunkte für eine bestimmte Aufgabe

hat
data2 <- data.frame(Start = c("8:01", "9:35", "10:42", "11:25", "14:22", 
    "17:20", "18:19"), End = c("8:22", "9:42", "11:20", "11:32", 
    "14:35", "18:15", "18:25"), stringsAsFactors=FALSE) 

Ich versuche, eine Spalte in data2 zu erstellen, die die IDs zur Verfügung stellt, um die Aufgabe basierend auf dem auszuführen Startzeit in Daten2. Die erwartete Ausgabe ist

data2$IdsAvail <- c("1, 2", "1, 2, 3, 4, 5, 6", "3, 4, 5, 6", 
    "1, 2, 5, 6", "1, 2, 3, 4", "3, 4, 5, 6", NA) 

Es ist wie unter

Daten2

Start End   IdsAvail 
1 8:01 8:22    1, 2 
2 9:35 9:42 1, 2, 3, 4, 5, 6 
3 10:42 11:20  3, 4, 5, 6 
4 11:25 11:32  1, 2, 5, 6 
5 14:22 14:35  1, 2, 3, 4 
6 17:20 18:15  3, 4, 5, 6 
7 18:19 18:25    <NA> 

Versuchte aussehen würde, um die IDs mit der Zeit in der Matrix zu entsprechen, kann aber nicht einen Weg finden. Es ist auch möglich, dass zwei Jobs innerhalb des Zeitrahmens kommen, in dem eine Person einen Job macht. Ich nehme das hier nicht in Betracht. Dies nur um die ersten verfügbaren IDs basierend auf der Matrix zu erhalten.

EDIT: Die untene Lösung von @Audiophile arbeitet für das Beispiel, aber es wirft eine Warnung hier mit Duplikaten

availability <- merge(availability,data2,by.x = 'time',by.y = 'slot',all.y = T) 

Ich hatte allow.cartesian zu verwenden, um es in dem ursprünglichen Datensatz zu arbeiten. Mein Dataset hat ungefähr 2000 Zeilen, nach der Verwendung von merge gibt es ungefähr> 20000 Zeilen. Der obige Schritt merge, der dieses Beispiel verwendet, gibt auch eine andere Anzahl von Zeilen als in 'Verfügbarkeit' oder 'Daten2'. Gibt es ein anderes Verfahren, d.h. foverlaps von data.table?

Antwort

2

Identifizieren Sie die Schlitze für die jede Person zur Verfügung steht, und es dann mit der Aufgabenliste fusionieren:

library(tidyr) 
library(dplyr) 

#Convert your availability matrix (mat1) to a data frame 
df <- as.data.frame(mat1) 
df$ID <- rownames(df) 

#Reshape the availability dataset 
availability <- df %>% 
    gather(time,available,-ID) %>% 
    filter(available==1) %>% 
    mutate(time = as.POSIXct(time,format = "%H:%M")) 

data1$Start_Time <- as.POSIXct(data1$Start_Time,format = "%H:%M") 
data2$Start <- as.POSIXct(data2$Start,format = "%H:%M") 

#Use start times to refine availability dataset 
availability <- merge(availability,data1,by = "ID") 
availability <- availability %>% 
    filter(time>=Start_Time) %>% 
    select(ID,time) 

#Round task time to nearest half hour slot 
data2$slot <- as.POSIXct(floor(as.double(data2$Start)/1800)*1800, 
         format = "%H:%M",origin = as.POSIXct('1970-01-01',tz='UTC')) 


availability <- merge(availability,data2,by.x = 'time',by.y = 'slot',all.y = T) 

availability <- availability %>% 
    select(Start,End,ID) %>% 
    arrange(Start,ID) %>% 
    group_by(Start,End) %>% 
    summarise(IdsAvail = toString(ID)) %>% 
    ungroup() %>% 
    mutate(Start = format(Start,"%H:%M")) 
+0

Danke für die Antwort. Es funktioniert gut mit dem Beispiel, zeigt aber einen Fehler über Duplikate beim Ausführen von 'merge (Verfügbarkeit, data2, by.x = 'Zeit', by.y = 'slot', all.y = T)' im ursprünglichen Dataset. Also muss ich 'allow.cartesian = TRUE' verwenden. Gibt es einen kompakten Weg? – kraj

Verwandte Themen