Я повинен перевірити спостереження за птахами, зроблені протягом більш тривалого періоду, на предмет дублювання / перекриття записів.
Спостерігачі з різних точок (A, B, C) зробили спостереження та позначили їх на паперових картах. Ті лінії, в які введено лінію, містять додаткові дані про види, точку спостереження та часові інтервали, які вони бачили.
Зазвичай спостерігачі спілкуються між собою по телефону під час спостереження, але іноді вони забувають, тому я отримую ці дублікати рядків.
Я вже зводив дані до тих рядків, які торкаються кола, тому мені не потрібно робити просторовий аналіз, а лише порівнювати інтервали часу для кожного виду і можу бути повністю впевненим, що це той самий індивід, який знайдений порівнянням .
Зараз я шукаю спосіб R визначити ті записи, які:
- виготовляються в той же день з інтервалом перекриття
- і де це той самий вид
- і які були зроблені з різних точок спостереження (A або B або C або ...))
У цьому прикладі я вручну знайшов можливі дублювання записів однієї особи. Точка спостереження різна (A <-> B), види однакові (Sst), а інтервал часу початку та кінця перекривається.
Тепер я створив би нове поле "дублікат" у своєму 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
циклів!