Отставшая функция в группе - PullRequest
0 голосов
/ 13 февраля 2020

Я хотел бы написать код для вычисления внутри каждой группы, сумма отстающих различий, как показано в таблице ниже:

ID  x rank  U   R   Required Output Value
1   1   1   U1  R1  -
1   1   2   U2  R2  R2-U1
1   1   3   U3  R3  (R3-U2) + (R3-U1)
1   1   4   U4  R4  (R4-U3) + (R4-U2) + (R4-U1)
1   0   5   U5  R5  R5
1   0   6   U6  R6  R6
1   0   7   U7  R7  R7
2   1   1   U8  R8  -
2   1   2   U9  R9  R9-U8
2   1   3   U10 R10 (R10-U9) + (R10 - U8)
2   1   4   U11 R11 (R11-U10) + (R11 - U9) + (R11 - U8)
3   1   1   U12 R12 -
3   0   2   U13 R13 R13
3   0   3   U14 R14 R14

ID - это уникальный идентификатор группы. х - это логическое значение, и в зависимости от его значения требуемый результат представляет собой либо сумму разницы с предыдущими значениями, либо значение того же периода «rank» - это столбец порядка ранга, и максимальный ранг может варьироваться в каждой группе. «U» и «R» являются основными интересующими столбцами.

Чтобы привести числовой пример, мне нужно следующее:

ID  x rank  U   R   Required Output Value
1   1   1   10  7   -
1   1   2   9   11  1
1   1   3   10  10  1 + 0 = 1
1   1   4   11  13  3+4+3 = 10
1   0   5   7   8   8
1   0   6   8   8   8
1   0   7   5   7   7
2   1   1   3   2   -
2   1   2   9   15  12
2   1   3   13  14  16
2   1   4   1   14  17
3   1   1   12  1   -
3   0   2   14  9   9
3   0   3   1   11  11

R код для создания этой таблицы:

ID = c(rep(1,7),rep(2,4),rep(3,3))
x = c(rep(1,4),rep(0,3),rep(1,5),rep(0,2))
rank = c(1:7,1:4,1:3)
U = c(10,9,10,11,7,8,5,3,9,13,1,12,14,1)
R = c(7,11,10,13,8,8,7,2,15,14,14,1,9,11)
dat = cbind(ID,x,rank,U,R)
colnames(dat)=c("ID","x","rank","U","R")

Ответы [ 2 ]

3 голосов
/ 13 февраля 2020

Вот решение tidyverse:

library(dplyr)
library(tidyr)

dat %>%
  as_tibble() %>%
  group_by(ID) %>%
  mutate(output = ifelse(x, lag(rank) * R - lag(cumsum(U)), R))

Результат:

# A tibble: 14 x 6
# Groups:   ID [3]
      ID     x  rank     U     R output
   <dbl> <dbl> <dbl> <dbl> <dbl>  <dbl>
 1     1     1     1    10     7     NA
 2     1     1     2     9    11      1
 3     1     1     3    10    10      1
 4     1     1     4    11    13     10
 5     1     0     5     7     8      8
 6     1     0     6     8     8      8
 7     1     0     7     5     7      7
 8     2     1     1     3     2     NA
 9     2     1     2     9    15     12
10     2     1     3    13    14     16
11     2     1     4     1    14     17
12     3     1     1    12     1     NA
13     3     0     2    14     9      9
14     3     0     3     1    11     11
1 голос
/ 13 февраля 2020

Вот базовое решение R с использованием ave

dat <- within(dat,output <- ave(R,ID,x, FUN = function(v) v*(seq(v)-1))-ave(U,ID,x, FUN = function(v) c(NA,cumsum(v)[-length(v)])))
dat <- within(dat, output <- ifelse(x==0,R,output))

, такое что

> dat
   ID x rank  U  R output
1   1 1    1 10  7     NA
2   1 1    2  9 11      1
3   1 1    3 10 10      1
4   1 1    4 11 13     10
5   1 0    5  7  8      8
6   1 0    6  8  8      8
7   1 0    7  5  7      7
8   2 1    1  3  2     NA
9   2 1    2  9 15     12
10  2 1    3 13 14     16
11  2 1    4  1 14     17
12  3 1    1 12  1     NA
13  3 0    2 14  9      9
14  3 0    3  1 11     11
...