У меня есть следующая таблица данных:
dt <- fread("
ID | EO_1 | EO_2 | EO_3 | GROUP
ID_001 | 0.5 | 1.2 | | A
ID_002 | | | | A
ID_003 | | | | A
ID_004 | | | | A
ID_001 | 0.4 | 2.5 | | B
ID_002 | | | | B
ID_003 | | | | B
ID_004 | | | | B
",
sep = "|",
colClasses = c("character", "numeric", "numeric", "numeric", "character"))
, и я пытаюсь выполнить некоторые построчные операции, которые иногда зависят от данных из предыдущих строк.Более конкретно:
calc_EO_1 <- function(
EO_1,
EO_2
){
EO_1 <- shift(EO_1, type = "lag") * shift(EO_2, type = "lag")
return(EO_1)
}
calc_EO_2 <- function(
EO_1,
EO_2,
EO_3
){
EO_2 <- EO_1 * shift(EO_2, type = "lag") * shift(EO_3, type = "lag")
return(EO_2)
}
calc_EO_3 <- function(
EO_1,
EO_2
){
EO_3 <- EO_1 * EO_2
return(EO_3)
}
Последний должен быть рассчитан из первой строки, так как он зависит от других полей (это должно быть легко), и после этого должны выполняться все три операции.последовательно и по строкам.
Самое близкое, что у меня было, было следующее:
first_row_bygroup_index <- dt[, .I[1], by = GROUP]$V1
dt[first_row_bygroup_index,
EO_3 := calc_EO_3(EO_1, EO_2)
]
dt[!first_row_bygroup_index,
`:=` (
EO_1 = calc_EO_1(EO_1, EO_2),
EO_2 = calc_EO_2(EO_1, EO_2, EO_3),
EO_3 = calc_EO_3(EO_1, EO_2)
),
by = row.names(dt[!first_row_bygroup_index])]
, но оно правильно вычисляет только первую строку:
ID | EO_1 | EO_2 | EO_3 | GROUP
ID_001 | 0.5 | 1.2 | 0.6 | A
ID_002 | | | | A
ID_003 | | | | A
ID_004 | | | | A
ID_001 | 0.4 | 2.5 | 1.0 | B
ID_002 | | | | B
ID_003 | | | | B
ID_004 | | | | B
Будучи этими космическими АН.
Не думаю, что я слишком далеко от решения, но я не могу найти способ заставить его работать.Проблема в том, что я не могу выполнять операции в подмножествах строк, используя строки из-за пределов подмножества.
РЕДАКТИРОВАТЬ Я пропустил ожидаемый результат:
ID | EO_1 | EO_2 | EO_3 | GROUP
ID_001 | 0.50000000 | 1.20000000 | 0.60000000 | A
ID_002 | 0.60000000 | 0.43200000 | 0.25920000 | A
ID_003 | 0.25920000 | 0.02902376 | 0.00752296 | A
ID_004 | 0.00752296 | 0.00000164 | 0.00000001 | A
ID_001 | 0.40000000 | 2.50000000 | 1.00000000 | B
ID_002 | 1.00000000 | 2.50000000 | 2.50000000 | B
ID_003 | 2.50000000 | 15.62500000 | 39.06250000 | B
ID_004 | 39.06250000 | 23841.8580000 | 931322.57810000 | B
NEW EDIT Я придумал следующий фрагмент, но я бы немного подождал, чтобы посмотреть, сможет ли кто-нибудь найти более эффективное решение, чем это:
while(any(is.na(dt))){
dt[, `:=` (
EO_3 = calc_EO_3(EO_1, EO_2),
EO_1 = ifelse(ID == "ID_001", EO_1, calc_EO_1(EO_1, EO_2)),
EO_2 = ifelse(ID == "ID_001", EO_2, calc_EO_2(EO_1, EO_2, EO_3))
)]
}
Я пришелс подобным решением dplyr, с этим уродливым исправлением цикла while.Ключ должен был бы найти способ сделать вычисление по ряду, которое могло бы получить информацию из строки раньше, даже если эта строка раньше была бы вне выбранного подмножества.Я надеюсь, что кто-то может улучшить это, поэтому я немного подожду, прежде чем пометить это как решение.