оценивать / сравнивать несколько строк и столбцов в кадре данных одновременно в R - PullRequest
0 голосов
/ 03 августа 2020

У меня есть следующий фрейм данных по отловам видов:

species <- c("pitalb", "gymruf", "thacas", "pitalb", "gymruf", "perruf", "denmer", "perruf", "pippip","wilpoe")
nt <- c(2,3,4,8,9,11,14,16,16,16)
date <- c((rep(as.POSIXct("1982-06-04 11:30:00"), 2)), as.POSIXct("1982-06-04 13:00:00"), 
          rep(as.POSIXct("1982-06-04 15:00:00"), 3), rep(as.POSIXct("1982-06-04 16:00:00"), 3),
ids <- c(rep("day 1", 10))
          as.POSIXct("1982-06-04 17:00:00"))
fake <- data.frame("species"=species, "net"=nt, "date"=date, "band.num"=bn, "ids"=ids)

выглядит так:

   species  net                 date  band.num    ids 
1   pitalb   2  1982-06-04 11:30:00       x100   day1
2   gymruf   3  1982-06-04 11:30:00       x109   day1
3   thacas   4  1982-06-04 13:00:00       x131   day1
4   pitalb   8  1982-06-04 15:00:00       x004   day1
5   gymruf   9  1982-06-04 15:00:00       x115   day1
6   perruf  11  1982-06-04 15:00:00       x006   day1
7   denmer  14  1982-06-04 16:00:00       x107   day1
8   perruf  16  1982-06-04 16:00:00       x128   day1
9   pippip  17  1982-06-04 16:00:00       x019   day1
10  wilpoe  16  1982-06-04 17:00:00       x010   day1

Цель состоит в том, чтобы создать вектор отловленных вместе особей, определенные критерии. Что-то похожее на это (paste (sizes, band.num, sep = ".")):

1 pitalb.x100
2 gymruf.x109
3 pitalb.x004
4 gymruf.x115
5 perruf.x006
6 denmer.x107
7 perruf.x128
8 wilpoe.x010

Критерии требуют, чтобы я сравнивал людей в нескольких строках и столбцах одновременно следующим образом:

*if* 
    1. an individual is captured within +/- 1 net AND 60 minutes of:
    two "pitalb" *OR* one "pitalb" and one "gymruf" *OR* one "denmer"

*or*
    2. a "perruf" is captured within +/- 2 nets *AND* 60 minutes of:
    two "pitalb" *OR* one "pitalb" and one "gymruf" *OR* one "denmer"

*then*
    paste(fake$sp, fake$bn, sep=".")

*else*
    0

Прямо сейчас я использую вложенные функции sapply для достижения этой цели. Код работает для критериев 1 , но я не понял, как добавить критерии 2 . Я предполагаю, что мне придется вложить третий sapply (), но я чувствую, что должен быть более простой способ сделать это. Вот как выглядит код на данный момент:

for (i in 1:length(unique(ids))) { 
  b.d <- subset(fake, fake$id==ids[i])               
  b.d$cn <- rep(1:nrow(b.d))    
  b.d <- arrange(b.d, date, nt)

instance <- unique(as.vector(sapply(b.d$cn, function(x) sapply(b.d$cn, function(y)
ifelse(abs(b.d$nt-b.d$nt[x]) <= 1 & abs(b.d$nt- b.d$nt[y]) <= 1   
         & abs(difftime(b.d$date, b.d$date[x], units = "mins")) <= 60
         & abs(difftime(b.d$date, b.d$date[y], units = "mins")) <= 60
          & ((b.d$species[x]=="pitalb" & b.d$species[y]=="pitalb") 
          | (b.d$species[x]=="pitalb" & b.d$species[y]=="gymruf")
          | (b.d$species[x]=="denmer"))
             & b.d$bn[x] != b.d$bn[y],0))))) }

Я думаю добавить

sapply(b.d$cn, function(z)

вложенный в

instance <- unique(as.vector(sapply(b.d$cn, function(x) sapply(b.d$cn, function(y) sapply(b.d$cn, function(z)

, а затем остальные критерии аналогично критериям 1 .

есть ли более простой способ сделать это? Я не очень опытный программист, поэтому уверен, что делаю это самым запутанным способом.

...