Ich muss die über einen längeren Zeitraum gemachten Vogelbeobachtungen auf doppelte / überlappende Einträge überprüfen.
Beobachter von verschiedenen Punkten (A, B, C) machten Beobachtungen und markierten sie auf Papierkarten. Diese Linien wurden in eine Linie gebracht, die zusätzliche Daten für die Art, den Beobachtungspunkt und die Zeitintervalle enthält, in denen sie gesehen wurden.
Normalerweise kommunizieren die Beobachter während des Beobachtens telefonisch miteinander, aber manchmal vergessen sie es, sodass ich diese doppelten Zeilen bekomme.
Ich habe die Daten bereits auf die Linien reduziert, die den Kreis berühren, sodass ich keine räumliche Analyse durchführen muss, sondern nur die Zeitintervalle für jede Art vergleiche und ziemlich sicher sein kann, dass es sich um dasselbe Individuum handelt, das durch den Vergleich gefunden wird .
Ich suche jetzt nach einer Möglichkeit in R, um die Einträge zu identifizieren, die:
- werden am selben Tag mit einem überlappenden Intervall erstellt
- und wo es die gleiche Art ist
- und die von verschiedenen Beobachtungspunkten (A oder B oder C oder ...) gemacht wurden)
In diesem Beispiel habe ich möglicherweise doppelte Einträge derselben Person manuell gefunden. Der Beobachtungspunkt ist unterschiedlich (A B), die Art ist dieselbe (Sst) und das Intervall der Start- und Endzeiten überschneidet sich.
Ich würde jetzt ein neues Feld "duplizieren" in meinem data.frame erstellen und beiden Zeilen eine gemeinsame ID geben, um sie exportieren und später entscheiden zu können, was zu tun ist.
Ich habe viel nach bereits verfügbaren Lösungen gesucht, aber keine gefunden, was die Tatsache betrifft, dass ich den Prozess für die Art (vorzugsweise ohne Schleife) unterteilen und die Zeilen für 2 + x Beobachtungspunkte vergleichen muss.
Einige Daten zum Herumspielen:
testdata <- structure(list(bird_id = c("20150712_0810_1410_A_1", "20150712_0810_1410_A_2",
"20150712_0810_1410_A_4", "20150712_0810_1410_A_7", "20150727_1115_1430_C_1",
"20150727_1120_1430_B_1", "20150727_1120_1430_B_2", "20150727_1120_1430_B_3",
"20150727_1120_1430_B_4", "20150727_1120_1430_B_5", "20150727_1130_1430_A_2",
"20150727_1130_1430_A_4", "20150727_1130_1430_A_5", "20150812_0900_1225_B_3",
"20150812_0900_1225_B_6", "20150812_0900_1225_B_7", "20150812_0907_1208_A_2",
"20150812_0907_1208_A_3", "20150812_0907_1208_A_5", "20150812_0907_1208_A_6"
), obsPoint = c("A", "A", "A", "A", "C", "B", "B", "B", "B",
"B", "A", "A", "A", "B", "B", "B", "A", "A", "A", "A"), species = structure(c(11L,
11L, 11L, 11L, 10L, 11L, 10L, 11L, 11L, 11L, 11L, 10L, 11L, 11L,
11L, 11L, 11L, 11L, 11L, 11L), .Label = c("Bf", "Fia", "Grr",
"Kch", "Ko", "Lm", "Rm", "Row", "Sea", "Sst", "Wsb"), class = "factor"),
from = structure(c(1436687150, 1436689710, 1436691420, 1436694850,
1437992160, 1437991500, 1437995580, 1437992360, 1437995960,
1437998360, 1437992100, 1437994000, 1437995340, 1439366410,
1439369600, 1439374980, 1439367240, 1439367540, 1439369760,
1439370720), class = c("POSIXct", "POSIXt"), tzone = ""),
to = structure(c(1436687690, 1436690230, 1436691690, 1436694970,
1437992320, 1437992200, 1437995600, 1437992400, 1437996070,
1437998750, 1437992230, 1437994220, 1437996780, 1439366570,
1439370070, 1439375070, 1439367410, 1439367820, 1439369930,
1439370830), class = c("POSIXct", "POSIXt"), tzone = "")), .Names = c("bird_id",
"obsPoint", "species", "from", "to"), row.names = c("20150712_0810_1410_A_1",
"20150712_0810_1410_A_2", "20150712_0810_1410_A_4", "20150712_0810_1410_A_7",
"20150727_1115_1430_C_1", "20150727_1120_1430_B_1", "20150727_1120_1430_B_2",
"20150727_1120_1430_B_3", "20150727_1120_1430_B_4", "20150727_1120_1430_B_5",
"20150727_1130_1430_A_2", "20150727_1130_1430_A_4", "20150727_1130_1430_A_5",
"20150812_0900_1225_B_3", "20150812_0900_1225_B_6", "20150812_0900_1225_B_7",
"20150812_0907_1208_A_2", "20150812_0907_1208_A_3", "20150812_0907_1208_A_5",
"20150812_0907_1208_A_6"), class = "data.frame")
Ich habe eine Teillösung mit der Funktion data.table gefunden, die zB hier /programming//q/25815032 erwähnt wird
library(data.table)
#Subsetting the data for each observation point and converting them into data.tables
A <- setDT(testdata[testdata$obsPoint=="A",])
B <- setDT(testdata[testdata$obsPoint=="B",])
C <- setDT(testdata[testdata$obsPoint=="C",])
#Set a key for these subsets (whatever key exactly means. Don't care as long as it works ;) )
setkey(A,species,from,to)
setkey(B,species,from,to)
setkey(C,species,from,to)
#Generate the match results for each obsPoint/species combination with an overlapping interval
matchesAB <- foverlaps(A,B,type="within",nomatch=0L) #nomatch=0L -> remove NA
matchesAC <- foverlaps(A,C,type="within",nomatch=0L)
matchesBC <- foverlaps(B,C,type="within",nomatch=0L)
Natürlich "funktioniert" das irgendwie, aber es ist wirklich nicht das, was ich am Ende gerne erreichen möchte.
Zuerst muss ich die Beobachtungspunkte hart codieren. Ich würde es vorziehen, eine Lösung mit einer beliebigen Anzahl von Punkten zu finden.
Zweitens liegt das Ergebnis nicht in einem Format vor, mit dem ich wirklich problemlos wieder arbeiten kann. Die übereinstimmenden Zeilen werden tatsächlich in dieselbe Zeile eingefügt, während mein Ziel darin besteht, die Zeilen darunter einzufügen, und in einer neuen Spalte würden sie eine gemeinsame Kennung haben.
Drittens muss ich erneut manuell prüfen, ob sich ein Intervall von allen drei Punkten überschneidet (was bei meinen Daten nicht der Fall ist, aber im Allgemeinen möglich ist).
Am Ende möchte ich nur einen neuen data.frame mit allen Kandidaten erhalten, die durch eine Gruppen-ID identifiziert werden können, die ich wieder mit den Zeilen verbinden und das Ergebnis als Ebene zur weiteren Prüfung exportieren kann.
Also noch jemand Ideen, wie das geht?
for
Schleifen verwendet!