#r #dplyr #group-by
#r #dplyr #группировать по
Вопрос:
У меня есть фрейм данных / tibble, который выглядит следующим образом:
# A tibble: 15 x 2
# Groups: id [3]
id date
<int> <date>
1 1 1998-02-13
2 1 1998-02-14
3 1 1998-02-15
4 1 1998-02-16
5 1 1998-02-17
6 2 1998-02-13
7 2 1998-02-14
8 2 1998-02-15
9 2 1998-02-16
10 2 1998-02-17
11 3 1998-02-13
12 3 1998-02-14
13 3 1998-02-15
14 3 1998-02-16
15 3 1998-02-17
Я хотел бы добавить переменную «days_before_event», которая будет считаться от 1: 5 (но это не должно быть жестко запрограммировано, а скорее быть элементами для каждой группы). Я думал о том, чтобы сделать что-то вроде этого
df_long %>% mutate(days_before_event = 1:nrow(.))
где nrow(.)
должно быть количество строк в группе. Это не работает и показывает ошибку
Fehler: Problem with `mutate()` input `days_before_event`.
x Input `days_before_event` can't be recycled to size 5.
i Input `days_before_event` is `1:nrow(.)`.
i Input `days_before_event` must be size 5 or 1, not 15.
i The error occurred in group 1: id = 1.
Любой трюк о том, как я могу этого добиться?
Ответ №1:
Мы можем использовать row_number
вместо 1:nrow
library(dplyr)
df_long %>%
mutate(days_before_event =row_number())
Или с помощью base R
, используйте ave
для группировки по «идентификатору» и получения последовательности ( seq_along
)
df_long$days_before_event <- with(df_long, ave(seq_along(id),
id, FUN = seq_along))
Ошибка заключается в том, что это сгруппированный набор данных (из атрибута group, отображаемого в печатных данных), поэтому 1:nrow получит последовательность от 1-й до последней строки всего набора данных, а не последней строки группы. Это создает дисбаланс length
и mutate
может возвращать только выходные данные, совпадающие length
с исходными данными (или их нужно переносить в a list
)
Комментарии:
1. потрясающе, большое спасибо!! Если бы я хотел использовать базовый r, вы знаете, как я мог бы достичь той же цели?
2. о, вау, большое вам спасибо! База r напрямую выглядит более устрашающе, ха-ха
3. @RobinKohrs В data.table он намного компактнее
setDT(df_long)[, days_before_event := rowid(id)]
4. спасибо большое! Я никогда не рассматривал data.table, поскольку на самом деле я не работаю с большими наборами данных. Я думал, что можно отказаться от более простого sytax для более быстрой обработки. Но, возможно, стоит подробнее изучить это:)