Верхние 5 и нижние 5 в r с помощью Group_by - PullRequest
0 голосов
/ 27 марта 2020

Я ищу код или функцию, которая присваивает значение 5 самым высоким значениям и 5 самым низким значениям. Например, это может быть набор данных, подобный следующему:

df <- data.frame(
   Date = c(rep("2010-01-31",16), rep("2010-02-28", 14)), 
   Value=c(rep(c(1,2,3,4,5,6,7,8,9,NA,NA,NA,NA,NA,15),2))
)

Редактировать: это просто пример данных. Данные, которые я использую, являются более сложными, и поэтому код должен учитывать переменную длину столбца Date, а также несколько пропущенных значений (NA).

Затем я хотел бы получить значение, назначенное пяти наименьшее значение равно «5w» и «5b» для 5 самых высоких значений. Затем данные должны быть заключены в group_by на основе даты, чтобы процесс повторялся в каждом периоде. Я пытался использовать процентиль, но этот метод не поддерживает постоянное количество значений в каждой скобке. Поэтому я ищу метод, который позволяет число значений в каждой скобке быть постоянным. Если это возможно, было бы неплохо поставить все фирмы в скобки по 5%. Под этим я имею в виду 20 скобок со всеми распределенными фирмами. Это означает, что лучшая скобка будет состоять из 5% всех фирм с самой высокой стоимостью. Значения могут быть 0:19. Т.е. это означает, что ожидаемый результат фирмы в наивысшей стоимости будет равен 19, а фирма в самой низкой скобке получит значение 0.

Заранее спасибо

Ответы [ 2 ]

1 голос
/ 27 марта 2020

Heads up: хотя я подозреваю, что это только примерные данные, у вас есть два 1 s в 2010-01-31. Этот код объясняет это, но при отсутствии сортировки вывод выглядит странно. Для этого я добавляю arrange, чтобы показать их.

Я использую здесь min_rank, предполагая, что вы не хотите связей, а всегда хотите сверху / снизу 5. Альтернатива равно dense_rank, что обозначило бы верхнюю шесть из 2010-01-31 из-за t ie для 1.

library(dpyr)
dat %>%
  group_by(Date) %>%
  mutate(
    R = min_rank(Value),
    Quux = case_when(
      R < 6       ~ "5w",
      R > n() - 5 ~ "5b",
      TRUE        ~ NA_character_)
    ) %>%
  ungroup() %>%
  arrange(Date, Value) %>%
  print(n=99)
# # A tibble: 30 x 4
#    Date       Value     R Quux 
#    <fct>      <int> <int> <chr>
#  1 2010-01-31     1     1 5w   
#  2 2010-01-31     1     1 5w   
#  3 2010-01-31     2     3 5w   
#  4 2010-01-31     3     4 5w   
#  5 2010-01-31     4     5 5w   
#  6 2010-01-31     5     6 <NA> 
#  7 2010-01-31     6     7 <NA> 
#  8 2010-01-31     7     8 <NA> 
#  9 2010-01-31     8     9 <NA> 
# 10 2010-01-31     9    10 <NA> 
# 11 2010-01-31    10    11 <NA> 
# 12 2010-01-31    11    12 5b   
# 13 2010-01-31    12    13 5b   
# 14 2010-01-31    13    14 5b   
# 15 2010-01-31    14    15 5b   
# 16 2010-01-31    15    16 5b   
# 17 2010-02-28     2     1 5w   
# 18 2010-02-28     3     2 5w   
# 19 2010-02-28     4     3 5w   
# 20 2010-02-28     5     4 5w   
# 21 2010-02-28     6     5 5w   
# 22 2010-02-28     7     6 <NA> 
# 23 2010-02-28     8     7 <NA> 
# 24 2010-02-28     9     8 <NA> 
# 25 2010-02-28    10     9 <NA> 
# 26 2010-02-28    11    10 5b   
# 27 2010-02-28    12    11 5b   
# 28 2010-02-28    13    12 5b   
# 29 2010-02-28    14    13 5b   
# 30 2010-02-28    15    14 5b   

Редактировать используя недавно обнаруженные данные. Я делаю вывод, что значения NA следует игнорировать и рассматривать только ранжированные. Это показывает условие, в котором нет 10 строк с общим значением, поскольку 2010-02-28 предоставляет только 4 5b.

dat %>%
  group_by(Date) %>%
  mutate(
    R = min_rank(Value),
    Quux = case_when(
      R < 6                        ~ "5w",
      R > max(R, na.rm = TRUE) - 5 ~ "5b",
      TRUE                         ~ NA_character_)
    ) %>%
  ungroup() %>%
  arrange(Date, Value) %>%
  print(n=99)

# # A tibble: 30 x 4
#    Date       Value     R Quux 
#    <fct>      <dbl> <int> <chr>
#  1 2010-01-31     1     1 5w   
#  2 2010-01-31     1     1 5w   
#  3 2010-01-31     2     3 5w   
#  4 2010-01-31     3     4 5w   
#  5 2010-01-31     4     5 5w   
#  6 2010-01-31     5     6 <NA> 
#  7 2010-01-31     6     7 5b   
#  8 2010-01-31     7     8 5b   
#  9 2010-01-31     8     9 5b   
# 10 2010-01-31     9    10 5b   
# 11 2010-01-31    15    11 5b   
# 12 2010-01-31    NA    NA <NA> 
# 13 2010-01-31    NA    NA <NA> 
# 14 2010-01-31    NA    NA <NA> 
# 15 2010-01-31    NA    NA <NA> 
# 16 2010-01-31    NA    NA <NA> 
# 17 2010-02-28     2     1 5w   
# 18 2010-02-28     3     2 5w   
# 19 2010-02-28     4     3 5w   
# 20 2010-02-28     5     4 5w   
# 21 2010-02-28     6     5 5w   
# 22 2010-02-28     7     6 5b   
# 23 2010-02-28     8     7 5b   
# 24 2010-02-28     9     8 5b   
# 25 2010-02-28    15     9 5b   
# 26 2010-02-28    NA    NA <NA> 
# 27 2010-02-28    NA    NA <NA> 
# 28 2010-02-28    NA    NA <NA> 
# 29 2010-02-28    NA    NA <NA> 
# 30 2010-02-28    NA    NA <NA> 
0 голосов
/ 27 марта 2020

Попробуйте это

library(dplyr)

DF <- data.frame(Date = c(rep("2010-01-31",16), rep("2010-02-28", 14)), Value=c(rep(1:15,2)))

DF %>% 
  group_by(Date) %>%
  mutate(n = row_number(),
         nn = 1 + max(n) - n) %>%
  ungroup() %>%
  filter(n <= 5 | nn <= 5) %>%
  mutate(v1 = if_else(n <= 5, "5b", "5w")) %>%
  select(-n, -nn)

Вывод

# A tibble: 20 x 3
   Date       Value v1   
   <fct>      <int> <chr>
 1 2010-01-31     1 5b   
 2 2010-01-31     2 5b   
 3 2010-01-31     3 5b   
 4 2010-01-31     4 5b   
 5 2010-01-31     5 5b   
 6 2010-01-31    12 5w   
 7 2010-01-31    13 5w   
 8 2010-01-31    14 5w   
 9 2010-01-31    15 5w   
10 2010-01-31     1 5w   
11 2010-02-28     2 5b   
12 2010-02-28     3 5b   
13 2010-02-28     4 5b   
14 2010-02-28     5 5b   
15 2010-02-28     6 5b   
16 2010-02-28    11 5w   
17 2010-02-28    12 5w   
18 2010-02-28    13 5w   
19 2010-02-28    14 5w   
20 2010-02-28    15 5w  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...