Je dois vérifier les observations d'oiseaux faites sur une période plus longue pour les entrées en double / qui se chevauchent.
Des observateurs de différents points (A, B, C) ont fait des observations et les ont marquées sur des cartes papier. Ces lignes ont été introduites dans une ligne avec des données supplémentaires pour l'espèce, le point d'observation et les intervalles de temps où elles ont été vues.
Normalement, les observateurs communiquent entre eux par téléphone pendant l'observation, mais parfois ils oublient, donc je reçois ces lignes en double.
J'ai déjà réduit les données aux lignes qui touchent le cercle, donc je n'ai pas à faire d'analyse spatiale, mais je compare seulement les intervalles de temps pour chaque espèce et je peux être sûr que c'est le même individu que l'on trouve par la comparaison .
Je cherche maintenant un moyen dans R d'identifier les entrées qui:
- sont faites le même jour avec un intervalle qui se chevauchent
- et où c'est la même espèce
- et qui ont été faites à partir de différents points d'observation (A ou B ou C ou ...))
Dans cet exemple, j'ai trouvé manuellement des entrées éventuellement dupliquées de la même personne. Le point d'observation est différent (A <-> B), l'espèce est la même (Sst) et l'intervalle des heures de début et de fin se chevauche.
Je créerais maintenant un nouveau champ "dupliquer" dans mon data.frame, donnant aux deux lignes un identifiant commun pour pouvoir les exporter et décider plus tard quoi faire.
J'ai cherché beaucoup de solutions déjà disponibles, mais je n'ai trouvé aucune préoccupation concernant le fait que je dois sous-définir le processus pour l'espèce (de préférence sans boucle) et comparer les lignes pour 2 + x points d'observation.
Quelques données avec lesquelles jouer:
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")
J'ai trouvé une solution partielle avec les foverlaps de la fonction data.table mentionnés par exemple ici 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)
Bien sûr, cela "fonctionne" en quelque sorte, mais ce n'est vraiment pas ce que j'aime à la fin.
Tout d'abord, je dois coder en dur les points d'observation. Je préférerais trouver une solution prenant un nombre arbitraire de points.
Deuxièmement, le résultat n'est pas dans un format avec lequel je peux vraiment recommencer à travailler facilement. Les lignes correspondantes sont en fait placées dans la même ligne, alors que mon objectif est de placer les lignes en dessous, et dans une nouvelle colonne, elles auraient un identifiant commun.
Troisièmement, je dois vérifier à nouveau manuellement, si un intervalle chevauche les trois points (ce qui n'est pas le cas avec mes données, mais le pourrait généralement)
En fin de compte, je voudrais simplement recevoir un nouveau data.frame avec tous les candidats identifiables par un identifiant de groupe que je peux joindre aux lignes et exporter le résultat sous forme de couche pour un examen plus approfondi.
Alors, quelqu'un a-t-il d'autres idées sur la façon de procéder?
for
boucles!