2017-12-18 1 views
-1

Ich arbeite mit GPS-Halsbanddaten von Wildtieren. GPS-Halsbänder werden anhand der Seriennummer identifiziert. Ein einzelner GPS-Halsband kann im Laufe von einigen Jahren für mehrere Tiere verwendet werden. Ich muss jedem Datenpunkt eine Tier-ID von einem GPS-Halsband zuordnen. Die Tier-ID sollte der korrekten Kragennummer zugeordnet werden, jedoch nur für Orte, die am oder nach dem Fangdatum und am oder vor dem Sterblichkeitsdatum (falls zutreffend) dieses Tieres genommen wurden.Joining zwei Tabellen basierend auf Kriterien über mehrere Spalten

Das folgende Beispiel zeigt, wie meine Daten aussehen.

Wenn die GPS-Kragen Daten über Satelliten heruntergeladen es in folgendem Format ist:

CollarSerialNumber Latitude Longitude  Date 
1    36542 44.95511 -107.5431 2016-02-18 
2    36542 44.94927 -107.5855 2016-02-19 
3    36542 44.95027 -107.5838 2016-02-20 
4    36542 44.96125 -107.5831 2016-02-20 
5    36542 44.95949 -107.5854 2016-02-21 
6    36542 44.95233 -107.5717 2016-02-21 
7    36542 44.95743 -107.5664 2016-02-22 
8    36542 44.96124 -107.5840 2016-02-22 
9    36542 44.96322 -107.5799 2016-02-22 
10    36542 44.95912 -107.5857 2016-02-23 
11    36545 44.95263 -107.5207 2016-02-17 
12    36545 44.95278 -107.5202 2016-02-17 
13    36545 44.95366 -107.5481 2016-02-18 
14    36545 44.93453 -107.5940 2016-02-19 
15    36545 44.94563 -107.5823 2016-02-19 
16    36545 44.95020 -107.5836 2016-02-20 

Ich habe einen separaten Datenrahmen, die Erfassung Daten von Tieren enthält (dh das Datum des Kragen auf dem Tiere eingesetzt wurde), Tier IDs und Sterblichkeitsdaten.

Animal_ID Collar_Serial Capture_Date Mort_Date 
1 16-046   36542 2016-02-18 2016-02-20 
2 16-047   36542 2016-02-21   NA 
3 16-048   36545 2016-02-17   NA 

Also brauche ich eine Animal_ID Spalte mit den GPS-Kragen-Daten hinzuzufügen, die Animal_ID anzeigt, basierend auf dem Kragen Serial # und Capture and Mortality Daten. Meine erwartete Ausgabe wäre folgende:

CollarSerialNumber Latitude Longitude  Date Animal_ID 
1    36542 44.95511 -107.5431 2016-02-18 16-046 
2    36542 44.94927 -107.5855 2016-02-19 16-046 
3    36542 44.95027 -107.5838 2016-02-20 16-046 
4    36542 44.96125 -107.5831 2016-02-20 16-046 
5    36542 44.95949 -107.5854 2016-02-21 16-047 
6    36542 44.95233 -107.5717 2016-02-21 16-047 
7    36542 44.95743 -107.5664 2016-02-22 16-047 
8    36542 44.96124 -107.5840 2016-02-22 16-047 
9    36542 44.96322 -107.5799 2016-02-22 16-047 
10    36542 44.95912 -107.5857 2016-02-23 16-047 
11    36545 44.95263 -107.5207 2016-02-17 16-048 
12    36545 44.95278 -107.5202 2016-02-17 16-048 
13    36545 44.95366 -107.5481 2016-02-18 16-048 
14    36545 44.93453 -107.5940 2016-02-19 16-048 
15    36545 44.94563 -107.5823 2016-02-19 16-048 
16    36545 44.95020 -107.5836 2016-02-20 16-048 
+0

Haben Sie überhaupt etwas versucht? Wo bist du stecken geblieben? – MrFlick

+0

Ihre Frage ist nicht klar (für mich). Muss "Date" von den GPS-Daten mit "Capture_Date" oder "Mort_Date" übereinstimmen? Können Sie Ihre Frage bearbeiten, um Ihre erwartete Ausgabe für die von Ihnen angegebenen Beispieldaten einzubeziehen? –

+0

@MauritsEvers Ich habe die Frage mit der erwarteten Ausgabe bearbeitet. Hoffentlich ist es jetzt klarer. – bfuda

Antwort

0

Ich habe eine ziemlich klobige Lösung für mein Problem, aber es funktioniert. Siehe unten:

#get all Animal_IDs from capture dataset 
allID = unique(capdat$Animal_ID) 

#create list to hold data frames, one df for each animalID 
df.list <- as.list(rep("", length(allID))) 

#loop through each animal ID, find matching collar serial #, capture date, 
#and mortality date (if applicable) 
for (i in 1:length(allID)){ 
    ID.i = allID[i] 
    ser.i <- pull(capdat[capdat$Animal_ID == ID.i, 4]) 
    capdate.i = pull(capdat[capdat$Animal_ID == ID.i, 2]) 
    mortdate.i = pull(capdat[capdat$Animal_ID == ID.i, 11]) 

    ifelse(is.na(mortdate.i), 
     df.list[[i]] <- dat[(dat$CollarSerialNumber == ser.i & 
          dat$Date > capdate.i) ,], 
     df.list[[i]] <- dat[(dat$CollarSerialNumber == ser.i & 
          dat$Date > capdate.i & dat$Date < mortdate.i) ,]) 
    df.list[[i]]$Animal_ID = ID.i 
    } 

#merge list into a single data frame 
df <- ldply(df.list, data.frame) 

Wenn jemand mit einer eleganteren Lösung kommen kann, würde ich es gerne sehen!

Verwandte Themen