Метод Base R с использованием lapply
, предполагая, что у вас есть уникальные годы в df
, мы можем отфильтровать рамки для каждого year
, упорядочить их по столбцу action
и добавить столбец rank
с номером строки.
do.call(rbind, lapply(sort(df$year), function(x) {
temp = df[df$year <= x, ]
transform(year = x,temp[order(temp$actions,decreasing = TRUE), ],
rank = 1:nrow(temp))
}))
# id actions year rank
#4 f 109 1994 1
#41 f 109 1995 1
#1 b 2 1995 2
#42 f 109 1996 1
#3 e 53 1996 2
#11 b 2 1996 3
#2 c 156 1997 1
#43 f 109 1997 2
#31 e 53 1997 3
#12 b 2 1997 4
Если мы хотим сделать это, используя tidyverse
инструменты, мы можем сделать
map_dfr(sort(df$year), function(x)
df %>%
filter(year <= x) %>%
arrange(desc(actions)) %>%
mutate(year = x,
rank = row_number()))
# id actions year rank
#1 f 109 1994 1
#2 f 109 1995 1
#3 b 2 1995 2
#4 f 109 1996 1
#5 e 53 1996 2
#6 b 2 1996 3
#7 c 156 1997 1
#8 f 109 1997 2
#9 e 53 1997 3
#10 b 2 1997 4
Как работает подход tidyverse
:
Любой тип map..
используется для циклического прохождения каждого переданного элемента (здесь year
).map_dfr
означает, что он ожидает, что выходные данные каждой операции будут представлять собой фрейм данных (df
из map_dfr
), и он будет связывать все выходные данные фрейма вместе (r
из map_dfr
), также есть map_dfc
который связывает выходные данные.
Теперь для каждых year
it filters
df
для year
значений, которые меньше, чем текущее значение (x
), затем упорядочивает кадр данных внисходящий (desc
) порядок, основанный на значениях в actions
.Создает два новых столбца, используя mutate
, первый из которых year
(уже существующий столбец year
заменен) получает текущее значение year
, равное x
, а столбец rank
дает добавочный номер строкидля каждой строки в кадре данных.
Чтобы понять подробности операции, я бы посоветовал вам выполнить шаги вручную для каждого year
.
Таким образом, для первого года 1994
это дает вывод как
df %>%
filter(year <= 1994) %>%
arrange(desc(actions)) %>%
mutate(year = 1994,
rank = row_number())
# id actions year rank
#1 f 109 1994 1
Для 1995
это дает вывод
df %>%
filter(year <= 1995) %>%
arrange(desc(actions)) %>%
mutate(year = 1995,
rank = row_number())
# id actions year rank
#1 f 109 1995 1
#2 b 2 1995 2
и так далее, итерация для каждого year
.Таким образом, для каждого year
вы получите такие кадры данных, и мы вместе свяжем окончательный результат.