Muszę sprawdzić obserwacje ptaków dokonane w dłuższym okresie pod kątem zduplikowanych / pokrywających się wpisów.
Obserwatorzy z różnych punktów (A, B, C) dokonali obserwacji i oznaczyli je na papierowych mapach. Linie te zostały umieszczone w linii z dodatkowymi danymi dla gatunku, punktem obserwacji i przedziałami czasu, w których były widoczne.
Zwykle obserwatorzy komunikują się ze sobą przez telefon podczas obserwacji, ale czasami zapominają, więc otrzymuję te duplikaty.
Już zredukowałem dane do tych linii, które dotykają okręgu, więc nie muszę dokonywać analizy przestrzennej, a jedynie porównywać przedziały czasowe dla każdego gatunku i mogę być całkiem pewien, że jest to ta sama osoba znaleziona w porównaniu .
Teraz szukam sposobu w R, aby zidentyfikować te wpisy, które:
- są wykonywane tego samego dnia z nakładającymi się interwałami
- i gdzie jest to ten sam gatunek
- i które zostały wykonane z różnych punktów obserwacyjnych (A lub B lub C lub ...)
W tym przykładzie ręcznie znalazłem ewentualnie zduplikowane wpisy tej samej osoby. Punkt obserwacyjny jest inny (A <-> B), gatunek jest taki sam (Sst), a przedział czasu rozpoczęcia i zakończenia nakładają się.
Teraz utworzę nowe pole „duplikat” w mojej data.frame, nadając obu wierszom wspólny identyfikator, aby móc je wyeksportować, a następnie zdecydować, co robić.
Dużo szukałem już dostępnych rozwiązań, ale nie znalazłem żadnego związku z faktem, że muszę podgrupować proces dla gatunku (najlepiej bez pętli) i muszę porównać rzędy dla 2 + x punktów obserwacyjnych.
Niektóre dane do zabawy:
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")
Znalazłem częściowe rozwiązanie ze wspomnianymi foverlapsami funkcji data.table, np. Tutaj https://stackoverflow.com/q/25815032
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)
Oczywiście, to jakoś „działa”, ale tak naprawdę to nie to, co lubię w końcu osiągnąć.
Najpierw muszę zakodować punkty obserwacyjne. Wolałbym znaleźć rozwiązanie przyjmujące dowolną liczbę punktów.
Po drugie, wynik nie jest w formacie, z którym naprawdę mogę łatwo wznowić pracę. Pasujące wiersze są w rzeczywistości wstawiane do tego samego wiersza, podczas gdy moim celem jest umieszczenie wierszy pod spodem, a w nowej kolumnie będą miały wspólny identyfikator.
Po trzecie, muszę ponownie sprawdzić ręcznie, czy interwał nakłada się na wszystkie trzy punkty (co nie jest prawdą w przypadku moich danych, ale ogólnie może)
Na koniec chciałbym tylko otrzymać nową ramkę danych ze wszystkimi kandydatami możliwymi do zidentyfikowania po identyfikatorze grupy, którą mogę dołączyć z powrotem do linii i wyeksportować wynik jako warstwę do dalszego badania.
Więc ktoś jeszcze pomysłów, jak to zrobić?
for
pętli!