Как вернуть среднее значение из последних n строк из другой группы (указано переменной)

У меня есть данные, как показано ниже:

data <- structure(list(seq = c(1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 
4L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 
6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 7L, 7L, 7L, 
7L, 7L, 8L, 8L, 9L, 9L, 9L, 10L, 10L, 10L), new_seq = c(2, 2, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
2, 2, 2, 2, NA, NA, NA, NA, NA, 4, 4, 4, 4, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, 6, 6, 6, 6, 6, NA, NA, 8, 8, 8, NA, NA, NA), value = c(2L, 
0L, 0L, 1L, 0L, 5L, 5L, 3L, 0L, 3L, 2L, 3L, 2L, 3L, 4L, 1L, 0L, 
0L, 0L, 1L, 1L, 0L, 2L, 5L, 3L, 0L, 1L, 0L, 0L, 0L, 1L, 1L, 3L, 
5L, 3L, 1L, 1L, 1L, 0L, 1L, 0L, 4L, 3L, 0L, 3L, 1L, 3L, 0L, 0L, 
1L, 0L, 0L, 3L, 4L, 5L, 3L, 5L, 3L, 5L, 0L, 1L, 1L, 3L, 2L, 1L, 
0L, 0L, 0L, 0L, 5L, 1L, 1L, 0L, 4L, 1L, 5L, 0L, 3L, 1L, 2L, 1L, 
0L, 3L, 0L, 1L, 1L, 3L, 0L, 1L, 1L, 2L, 2L, 1L, 0L, 4L, 0L, 0L, 
3L, 0L, 0L)), row.names = c(NA, -100L), class = c("tbl_df", "tbl", 
"data.frame"))

колонка new_seq относится к стоимости seq, Для каждого значения в new_seq который не NA Я хотел бы рассчитать среднее значение за последний 2 ряды value от соответствующих seq, Так, например, строки 1:2 нового столбца должен иметь значение 0.5 (среднее число строк 49:50), строки 51:54 также должен иметь значение 0.5 (среднее число строк 49:50 как хорошо) но строки 60:63 должен иметь значение 4 (среднее число строк 58:59). Как я могу сделать это с tidyverse?

2 ответа

Решение

Что-то вроде этого?

# calculate the mean value based on the last two rows of each seq
lookup <- data %>%
  group_by(seq) %>%
  mutate(rank = seq(n(), 1)) %>% 
  filter(rank <= 2) %>%
  summarise(new_column = mean(value)) %>%
  ungroup()

# match back to original dataset (only non-NA values of new_seq can be matched)
left_join(data, lookup, by = c("new_seq" = "seq"))

Результаты в:

# A tibble: 100 x 4
     seq new_seq value new.column
   <int>   <dbl> <int>      <dbl>
 1     1       2     2        0.5
 2     1       2     0        0.5
 3     2      NA     0       NA  
 4     2      NA     1       NA  
...

Ну это только половина tidyverse и я уверен, что кто-то может сделать лучше, но вот попытка.

group_by а также mutate облегчить вычисление среднего значения для последних 2 строк группы, но я не мог понять, как получить связь между seq а также new_seq так что я сделал это в базе R.

dat2 <- dat %>%
    group_by(seq) %>%
    mutate(end_val = (nth(value, -1L) + nth(value, -2L))/2)

dat3$result <- apply(dat2, 1, function(x) {
    dat2[dat2$seq == x['new_seq'], 'end_val'][[1]][1]
})

Вот результат. Я выделил соответствующие строки (так как в противном случае это было бы слишком долго, чтобы увидеть на экране сразу), но добавил исходные номера строк в качестве rowid колонка:

dat3 %>% tibble::rowid_to_column() %>% .[c(1:3,50:55,59:64),] 

# A tibble: 15 x 6
# Groups:   seq [6]
   rowid   seq new_seq value end_val result
   <int> <int>   <dbl> <int>   <dbl>  <dbl>
 1     1     1       2     2     1      0.5
 2     2     1       2     0     1      0.5
 3     3     2      NA     0     0.5   NA  
 4    50     2      NA     1     0.5   NA  
 5    51     3       2     0     3.5    0.5
 6    52     3       2     0     3.5    0.5
 7    53     3       2     3     3.5    0.5
 8    54     3       2     4     3.5    0.5
 9    55     4      NA     5     4     NA  
10    59     4      NA     5     4     NA  
11    60     5       4     0     2      4  
12    61     5       4     1     2      4  
13    62     5       4     1     2      4  
14    63     5       4     3     2      4  
15    64     6      NA     2     2     NA 
Другие вопросы по тегам