Это проще объяснить на примере. Рассмотрим эти данные:

library(dplyr)
n_data       = 20
set.seed(123)
data_standout = data.frame(group = sample(c('kids','monkeys','banana', 'latte'),
                                         size = n_data, replace=TRUE), 
                          time  = runif(n_data),
                          modality = sample(c('grande','small','large'),
                                            size = n_data, replace=TRUE),
                          stringsAsFactors = FALSE)
data_standin  = data.frame(group = c('kids','monkeys','banana', 'latte'), 
                           time = runif(4, 0, min(data_standout$time)), 
                           modality = rep('small', 4), stringsAsFactors = FALSE)

data_final    = bind_rows(data_standout, data_standin)

ОК. Теперь давайте рассмотрим одну группу в частности: обезьян.

# A tibble: 7 x 3
# Groups:   group [1]
    group       time modality
    <chr>      <dbl>    <chr>
1 monkeys 0.09211798    small
2 monkeys 0.17505265   grande
3 monkeys 0.32037324    large
4 monkeys 0.43489274    large
5 monkeys 0.46677904    small
6 monkeys 0.48861303   grande
7 monkeys 0.78229430    small

Группы упорядочены по времени и начинаются с появление modality == small.

Теперь я хочу создать новый столбец. Каждая строка в этом столбце должен указывать индекс последнего появления small внутри одной группы.

Итак, для группы обезьян значения этого столбца должны быть:

(NA, 1,1,1,1,5,5)

Скорость не является основным требованием, но dplyr является обязательным (остальная часть конвейера данных находится в dplyr).

1
user189035 16 Фев 2018 в 18:21

1 ответ

Лучший ответ

В качестве примера используйте данные monkeys:

monkeys %>% 
    arrange(time) %>% 
    group_by(group) %>% 
    mutate(small_idx = lag(cummax(ifelse(modality == 'small', seq_along(modality), 0))))

# A tibble: 7 x 4
# Groups:   group [1]
#    group       time modality small_idx
#   <fctr>      <dbl>   <fctr>     <dbl>
#1 monkeys 0.09211798    small        NA
#2 monkeys 0.17505265   grande         1
#3 monkeys 0.32037324    large         1
#4 monkeys 0.43489274    large         1
#5 monkeys 0.46677904    small         1
#6 monkeys 0.48861303   grande         5
#7 monkeys 0.78229430    small         5

< EM> Подробнее :

ifelse создает индексный вектор, который, если modality не мал, имеет нулевые значения;

with(monkeys, ifelse(modality == 'small', seq_along(modality), 0))
# [1] 1 0 0 0 5 0 7

cummax дает максимальный индекс small, наблюдаемый до сих пор:

cummax(with(monkeys, ifelse(modality == 'small', seq_along(modality), 0)))
# [1] 1 1 1 1 5 5 7

lag дает максимальный индекс small, замеченный ранее:

lag(cummax(with(monkeys, ifelse(modality == 'small', seq_along(modality), 0))))
# [1] NA  1  1  1  1  5  5
2
Psidom 16 Фев 2018 в 18:39