В моем экспериментальном проекте деревья измерены в разных лесах с повторными измерениями в разные годы
DT <- data.table(forest=rep(c("a","b"),each=6),
year=rep(c("2000","2010"),each=3),
id=c("1","2","3"),
size=(1:12))
DT[,id:=paste0(forest,id)]
> DT
forest year id size
1: a 2000 a1 1
2: a 2000 a2 2
3: a 2000 a3 3
4: a 2010 a1 4
5: a 2010 a2 5
6: a 2010 a3 6
7: b 2000 b1 7
8: b 2000 b2 8
9: b 2000 b3 9
10: b 2010 b1 10
11: b 2010 b2 11
12: b 2010 b3 12
Для каждого дерева i я хочу вычислить новую переменную, равную суммированию размера всех других людей в той же группе / году, которые больше, чем дерево i.
Я создал следующую функцию:
f.new <- function(i,n){
DT[forest==DT[id==i, unique(forest)] & year==n # select the same forest & year of the tree i
& size>DT[id==i & year==n, size], # select the trees larger than the tree i
sum(size, na.rm=T)] # sum the sizes of all such selected trees
}
При применении в таблице данных я получил правильные результаты.
DT[,new:=f.new(id,year), by=.(id,year)]
> DT
forest year id size new
1: a 2000 a1 1 5
2: a 2000 a2 2 3
3: a 2000 a3 3 0
4: a 2010 a1 4 11
5: a 2010 a2 5 6
6: a 2010 a3 6 0
7: b 2000 b1 7 17
8: b 2000 b2 8 9
9: b 2000 b3 9 0
10: b 2010 b1 10 23
11: b 2010 b2 11 12
12: b 2010 b3 12 0
Обратите внимание, что у меня есть большой набор данных с несколькими лесами (40) и повторными годами (6) и одиночными индивидуумами (20 000), в общей сложности почти 50 000 измерений. Когда я выполняю вышеуказанную функцию, это занимает 8-10 минут (Windows 7, процессор i5-6300U при 2,40 ГГц, 2,40 ГГц, ОЗУ 8 ГБ). Мне нужно повторять это часто с несколькими небольшими изменениями, и это занимает много времени.
- Есть ли более быстрый способ сделать это? Я проверил * apply функции, но не могу найти решение на их основе.
- Могу ли я создать универсальную функцию, которая не зависит от конкретной структуры набора данных (то есть я мог бы использовать в качестве «размера» различные столбцы)?