Маркируйте наблюдения путем ранжирования по нескольким столбцам, принимая во внимание связи - PullRequest
0 голосов
/ 25 августа 2018

У меня есть датафрейм, похожий на:

# A tibble: 15 x 5
   group name    sum count max_elements
   <int> <fct> <int> <int>        <int>
 1     1 aaa       3     2            4
 2     1 bbb       3     1            4
 3     1 ccc       2     2            4
 4     1 ddd       2     2            4
 5     1 eee       1     0            4
 6     2 aaa       3     2            3
 7     2 bbb       3     1            3
 8     2 ccc       2     3            3
 9     2 ddd       2     1            3
10     3 aaa       3     4            4
11     3 bbb       3     2            4
12     3 ccc       2     5            4
13     3 ddd       2     1            4
14     3 eee       2     1            4
15     3 fff       2     1            4

Я бы хотел обозначить каждое наблюдение в соответствии с этим решением:

  • упорядочить по группам все имена сначала по сумме, а затем по количеству
  • для каждой группы рассмотрим значение max_elements
  • для каждого имени, создайте метку как:

    • selected, если имя имеет высокую сумму и высокий счет в пределах максимального порога n-го элемента.
    • pick_random, если несколько имен имеют одинаковую сумму и одинаковое количество в пределах максимального порога n-го элемента.
    • not_selected, если он находится за пределами «расы»

Например, для group 1 результат будет выглядеть так:

# A tibble: 5 x 6
  group name  decision      sum count max_elements
  <int> <fct> <fct>       <int> <int>        <int>
1     1 aaa   selected        3     2            4
2     1 bbb   selected        3     1            4
3     1 ccc   pick_random     2     2            4
4     1 ddd   pick_random     2     2            4
5     1 eee   selected        1     0            4        

Для group 2 случайный выбор отсутствует, поскольку все имена набираются без связей в пределах максимального размера.

# A tibble: 4 x 6
  group name  decision       sum count max_elements
  <int> <fct> <fct>        <int> <int>        <int>
1     2 aaa   selected         3     2            3
2     2 bbb   selected         3     1            3
3     2 ccc   selected         2     3            3
4     2 ddd   not_selected     2     1            3

Для group 3 вместо:

# A tibble: 6 x 6
  group name  decision          sum count max_elements
  <int> <fct> <fct>           <int> <int>        <int>
1     3 aaa   selected            3     4            4
2     3 bbb   selected            3     2            4
3     3 ccc   selected            2     5            4
4     3 ddd   pick_random         2     1            4
5     3 eee   pick_random         2     1            4
6     3 fff   pick_random         2     1            4

Окончательный вывод df будет выглядеть так:

# A tibble: 15 x 6
   group name  decision          sum count max_elements
   <int> <fct> <fct>           <int> <int>        <int>
 1     1 aaa   selected            3     2            4
 2     1 bbb   selected            3     1            4
 3     1 ccc   pick_random         2     2            4
 4     1 ddd   pick_random         2     2            4
 5     1 eee   selected            1     0            4
 6     2 aaa   selected            3     2            3
 7     2 bbb   selected            3     1            3
 8     2 ccc   selected            2     3            3
 9     2 ddd   not_selected        2     1            3
10     3 aaa   selected            3     4            4
11     3 bbb   selected            3     2            4
12     3 ccc   selected            2     5            4
13     3 ddd   pick_random         2     1            4
14     3 eee   pick_random         2     1            4
15     3 fff   pick_random         2     1            4

Воспроизводимый df:

structure(list(group = c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 
3L, 3L, 3L, 3L, 3L, 3L), name = structure(c(1L, 2L, 3L, 4L, 5L, 
1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 5L, 6L), .Label = c("aaa", "bbb", 
"ccc", "ddd", "eee", "fff"), class = "factor"), sum = c(3L, 3L, 
2L, 2L, 1L, 3L, 3L, 2L, 2L, 3L, 3L, 2L, 2L, 2L, 2L), count = c(2L, 
1L, 2L, 2L, 0L, 2L, 1L, 3L, 1L, 4L, 2L, 5L, 1L, 1L, 1L), max_elements = c(4L, 
4L, 4L, 4L, 4L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 4L)), row.names = c(NA, 
-15L), class = c("tbl_df", "tbl", "data.frame"))

Пока я пытался организовать и использовать top_n. Но я не могу понять, как маркировать случаи, когда несколько наблюдений имеют одинаковое количество и одинаковую сумму.

df %>%
  group_by(group) %>%
  arrange(-sum, -count) %>%
  top_n(as.integer(max_elements))

1 Ответ

0 голосов
/ 25 августа 2018

Вот моя попытка решить ваш вопрос.Мы можем использовать rleid из пакета data.table для создания столбца Rank.После этого мы можем использовать case_when для назначения метки на основе условий.Обратите внимание, что важно расположить столбцы для правильного порядка, прежде чем применять это.Кажется, ты уже сделал это.Если нет, добавьте arrange(group, name, sum, count) в качестве первой операции конвейера.

library(tidyverse)
library(data.table)

dat2 <- dat %>%
  group_by(group, sum, count) %>%
  add_count() %>%
  group_by(group) %>%
  mutate(Rank = rleid(sum, count)) %>%
  mutate(decision = case_when(
    n > 1 & Rank <= max_elements   ~ "pick_random",
    Rank > max_elements            ~ "not_selected",
    TRUE                           ~ "selected",
  )) %>%
  ungroup() %>%
  select(group, name, decision, sum, count, max_elements) %>%
  mutate(decision = factor(decision))
dat2
# # A tibble: 15 x 6
#    group name  decision       sum count max_elements
#    <int> <fct> <fct>        <int> <int>        <int>
#  1     1 aaa   selected         3     2            4
#  2     1 bbb   selected         3     1            4
#  3     1 ccc   pick_random      2     2            4
#  4     1 ddd   pick_random      2     2            4
#  5     1 eee   selected         1     0            4
#  6     2 aaa   selected         3     2            3
#  7     2 bbb   selected         3     1            3
#  8     2 ccc   selected         2     3            3
#  9     2 ddd   not_selected     2     1            3
# 10     3 aaa   selected         3     4            4
# 11     3 bbb   selected         3     2            4
# 12     3 ccc   selected         2     5            4
# 13     3 ddd   pick_random      2     1            4
# 14     3 eee   pick_random      2     1            4
# 15     3 fff   pick_random      2     1            4
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...