Подгруппы внутри фрейма данных, основанные на соседних свойствах элемента
У меня есть эта структура данных ниже, и мне нужно создать столбец, основанный на связях с элементом 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)
Процедура расплава может позаботиться о возможных дубликатах А в пределах времени / площади.