Я стремлюсь оценить скалярное значение на основе формулы:
Z_t11(Z_t12 + Z_t13 + Z_t14) + Z_t12(Z_t13 + Z_t14) + Z_t13(Z_t14) +
Z_t21(Z_t22 + Z_t23 + Z_t24 + Z_t25) + Z_t22(Z_t23 + Z_t24 + Z_t25) + Z_t23(Z_t24 + Z_t25) + Z_t24(Z_t25)
Z_t11 — это Z
значение в Time 1
для ID 1
равно -1.5
Z_t13 — это Z
значение в Time 3
для ID 1
равно 0.5
ID Time Z
1 1 -1.5
1 2 -1.5
1 3 0.5
1 4 0.5
2 1 -0.5
2 2 -0.5
2 3 -2.0
2 4 -1.5
2 5 1.5
Как мне рассчитать:
-1.5*(-1.5+0.5+0.5) - 1.5*(0.5+0.5) + 0.5*(0.5) +
-0.5*(-0.5-2.0-1.5+1.5) -0.5*(-2.0-1.5+1.5) -2.0*(-1.5+1.5) -1.5*1.5
Сгруппировано по «ID», выполните цикл по row_number()
, используйте его в качестве индекса для извлечения значений «Z», которые успешны для каждой строки, получите sum
и умножьте на соответствующее значение «Z», а затем возьмите общее sum
library(dplyr)
library(purrr)
df1 %>%
group_by(ID) %>%
summarise(Z1 = sum(map_dbl(row_number(),
~ Z[.x] * sum(Z[row_number() > .x]))))
ПРИМЕЧАНИЕ. Для последней строки каждой группы возвращается 0, потому что для row_number() > n()
нет регистра.
df1 <- structure(list(ID = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L), Time = c(1L,
2L, 3L, 4L, 1L, 2L, 3L, 4L, 5L), Z = c(-1.5, -1.5, 0.5, 0.5,
-0.5, -0.5, -2, -1.5, 1.5)), class = "data.frame", row.names = c(NA,
-9L))
1) Для каждого идентификатора указанная функция дает требуемую сумму, а затем суммирует эти значения, рассчитанные для каждого идентификатора. Пакеты не используются.
with(DF, sum(tapply(Z, ID, function(z) sum(z * (sum(z) - cumsum(z))))))
## [1] -0.5
2) Другой подход состоит в том, чтобы преобразовать DF в широкую форму Z, а затем использовать манипуляции со строками в тексте выражения, показанного в вопросе, для преобразования ( в *( и Z_t11 в Z[1, 1] и т. д., а затем проанализировать и оценить это против Z. Пакеты не используются.
# next line is expression shown in question
s <- "Z_t11(Z_t12 + Z_t13 + Z_t14) + Z_t12(Z_t13 + Z_t14) + Z_t13(Z_t14) + Z_t21(Z_t22 + Z_t23 + Z_t24 + Z_t25) + Z_t22(Z_t23 + Z_t24 + Z_t25) + Z_t23(Z_t24 + Z_t25) + Z_t24(Z_t25)"
Z <- xtabs(Z ~., DF)
s |>
gsub(pattern = "\\(", replacement = "*(") |>
gsub(pattern = "_t(.)(.)", replacement = "[\\1, \\2]") |>
parse(file = "", n = NULL) |>
eval()
## [1] -0.5
Вход DF
в воспроизводимой форме:
Lines <- "ID Time Z
1 1 -1.5
1 2 -1.5
1 3 0.5
1 4 0.5
2 1 -0.5
2 2 -0.5
2 3 -2.0
2 4 -1.5
2 5 1.5"
DF <- read.table(text = Lines, header = TRUE)
Также числовое выражение, показанное в конце вопроса, оценивается следующим образом:
-1.5*(-1.5+0.5+0.5) - 1.5*(0.5+0.5) + 0.5*(0.5) +
-0.5*(-0.5-2.0-1.5+1.5) -0.5*(-2.0-1.5+1.5) -2.0*(-1.5+1.5) -1.5*1.5
## [1] -0.5