Подгруппы внутри фрейма данных, основанные на соседних свойствах элемента

У меня есть эта структура данных ниже, и мне нужно создать столбец, основанный на связях с элементом A в течение получаса до и после, а также присутствовать в соседних областях (сосед определен как +1 и -1 области).

ind area time
B   5   3/12/1981 7:20
D   6   3/12/1981 7:25
A   5   3/12/1981 7:40
B   4   3/12/1981 7:40
A   7   8/29/1982 10:00
A   31  9/12/1982 9:50
C   30  9/12/1982 9:50
A   69  4/10/1985 13:37

Желаемый результат - это столбец с примерами, в которых индивид находится в указанном диапазоне (в течение получаса до / после того, как индивидуум A присутствует, а также в интервале от +1 до -1 от области, где присутствует индивидуум A). В идеале это будет выглядеть так:

ind area    time    instance
B   5   3/12/1981 7:20  1
D   6   3/12/1981 7:25  1
A   5   3/12/1981 7:40  1
B   4   3/12/1981 7:40  1
A   7   8/29/1982 10:00 2
A   31  9/12/1982 9:50  3
C   30  9/12/1982 9:50  3
A   69  4/10/1985 13:37 4

В данном случае, например, присутствует индивидуум A вместе с любым другим индивидуумом, присутствующим в условиях времени и области. Если A обнаруживается один без каких-либо соседей по области и времени, он получает собственный экземпляр, как показано в экземплярах 2 и 4.

С точки зрения кода, я посчитал, что проще скопировать дату-время появления отдельного А в столбец как таковой:

ind area    time    instance
B   5   3/12/1981 7:20  3/12/1981 7:40
D   6   3/12/1981 7:25  3/12/1981 7:40
A   5   3/12/1981 7:40  3/12/1981 7:40
B   4   3/12/1981 7:40  3/12/1981 7:40
A   7   8/29/1982 10:00 8/29/1982 10:00
A   31  9/12/1982 9:50  9/12/1982 9:50
C   30  9/12/1982 9:50  9/12/1982 9:50
A   69  4/10/1985 13:37 4/10/1985 13:37

Который также работает в моей конкретной ситуации. Я не могу понять это главным образом из-за отсутствия ловкости с синтаксисом, связанным с характером проблемы под рукой. Насколько я понимаю, простой ifelse заявление не будет работать, и я не уверен, как sapply может сочетаться с этим.

Быстрое построение примера данных:

id<-c("B","D","A","B","A","A","C","A")
area<-c(5,6,5,4,7,31,30,69)
time<-as.POSIXct(c("3/12/1981 7:20","3/12/1981 7:25","3/12/1981 7:40","3/12/1981 7:40","8/29/1982 10:00","9/12/1982 9:50","9/12/1982 9:5
                   0","4/10/1985 13:37"),format="%m/%d/%Y %H:%M")

dat<-data.frame(id, area, time)

Моя попытка сводилась к этому, но с самого начала это было не так:

    dat$instance <- with(dat, sapply(time[ind==A], function(x) 
 ifelse(abs(area- area[ind==A & time == x]) <=1 & abs(difftime(time, x, units = "mins")) <= 30, time[ind=A],NA)
             )
)

Это попытка адаптировать коды, предоставленные Хенриком, thelatemail и Джастином, для решения проблемы, возникшей у меня несколько месяцев назад, по аналогичной проблеме, но с использованием поднабора. Извиняюсь, если есть эквивалентная проблема, уже перечисленная. Мне не удалось найти тот, который я мог бы интерпретировать.

1 ответ

Возможно это:

instance <- as.data.frame(with(dat, sapply(time[id=="A"], function(x) 
 ifelse(abs(area- area[id=="A" & time == x]) <=1 & abs(difftime(time, x, units = "mins")) <= 30, x,NA))))

datinstance=cbind(dat,instance)
melt(datinstance, id.vars=c("id","time","area"),na.rm=T)

Процедура расплава может позаботиться о возможных дубликатах А в пределах времени / площади.

Другие вопросы по тегам