Я должен проверить наблюдения за птицами, сделанные в течение более длительного периода для дублирующих / перекрывающихся записей.
Наблюдатели из разных точек (A, B, C) проводили наблюдения и отмечали их на бумажных картах. Те линии, которые были приведены в линию, содержат дополнительные данные о видах, точке наблюдения и временных интервалах, в которых они были замечены.
Обычно наблюдатели общаются друг с другом по телефону во время наблюдения, но иногда они забывают, поэтому я получаю эти дубликаты.
Я уже сократил данные до тех линий, которые касаются круга, поэтому мне не нужно делать пространственный анализ, а только сравнивать временные интервалы для каждого вида, и я могу быть совершенно уверен, что это тот же самый особь, который обнаружен при сравнении ,
Я сейчас ищу способ в R, чтобы определить те записи, которые:
- сделаны в один и тот же день с пересекающимся интервалом
- и где это тот же вид
- и которые были сделаны из разных точек наблюдения (A или B или C или ...))
В этом примере я вручную нашел, возможно, дублированные записи одного и того же человека. Точка наблюдения отличается (A <-> B), виды одинаковы (Sst) и интервал времени начала и окончания перекрывается.
Теперь я создал бы новое поле «duplicate» в моем data.frame, дав обеим строкам общий идентификатор, чтобы можно было их экспортировать, а затем решить, что делать.
Я много раз искал уже имеющиеся решения, но не нашел ни одного, касающегося того факта, что мне нужно подгруппировать процесс для вида (предпочтительно без петли) и сравнить строки для 2 + x точек наблюдения.
Некоторые данные, с которыми можно поиграться:
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")
Я нашел частичное решение с помощью функции data.table, упомянутой выше, например, здесь 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)
Конечно, это как-то «работает», но на самом деле это не то, чего я хотел бы достичь в конце.
Во-первых, мне нужно жестко закодировать точки наблюдения. Я бы предпочел найти решение с произвольным количеством точек.
Во-вторых, результат не в том формате, в котором я могу легко возобновить работу. Соответствующие строки фактически помещаются в одну и ту же строку, в то время как моя цель состоит в том, чтобы строки помещались внизу, а в новом столбце они имели бы общий идентификатор.
В-третьих, я должен снова проверить вручную, перекрывается ли интервал между всеми тремя точками (что не относится к моим данным, но, как правило, может)
В конце я просто хотел бы получить новый data.frame со всеми кандидатами, идентифицируемыми по идентификатору группы, чтобы я мог присоединиться к строкам и экспортировать результат в виде слоя для дальнейшего изучения.
Так у кого-нибудь еще идей как это сделать?
for
петли!