Разделение данных на квинтили с помощью group_by - PullRequest
1 голос
/ 29 марта 2020

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

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

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

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))

Впоследствии я также хотел бы проверить минимальный размер квинтилей, т. е. сколько точек данных являются минимальными в каждом квинтиле во всем наборе данных.

Ожидаемый результат будет выглядеть следующим образом:

structure(list(Date = structure(c(14640, 14640, 14640, 14640, 
14640, 14640, 14640, 14640, 14640, 14640, 14640, 14640, 14640, 
14640, 14640, 14640, 14668, 14668, 14668, 14668, 14668, 14668, 
14668, 14668, 14668, 14668, 14668, 14668, 14668, 14668), class = "Date"), 
    Value = c(1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 15, NA, NA, NA, NA, 
    NA, 2, 3, 4, 5, 6, 7, 8, 9, 15, NA, NA, NA, NA, NA), R = c(1L, 
    1L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, NA, NA, NA, NA, 
    NA, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, NA, NA, NA, NA, NA
    ), S_P = c("Worst", "Worst", "Worst", NA, NA, NA, NA, "Best", 
    "Best", "Best", NA, NA, NA, NA, NA, NA, "Worst", "Worst", NA, NA, 
    NA, NA, NA, "Best", "Best", NA, NA, NA, NA, NA)), row.names = c(NA, 
-30L), class = c("tbl_df", "tbl", "data.frame"))

Ответы [ 2 ]

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

Когда я вас правильно понимаю, вы хотите присвоить вашему столбцу «Значение» и пометить тех, кто имеет ранг ниже квантиля 20%, как «худший», а тех, кто выше 80%, как «лучший». После этого вам понадобится таблица.

Вы можете использовать ave как для идентификации rank, так и для идентификации quantile. Функция quantile дает три группы, которые можно идентифицировать с помощью findInterval, кодировать как переменную factor и помечать их по желанию. Однако я не уверен, какие ранги следует включить в квантили, поэтому я делаю кодировку E_P в двух отдельных столбцах для сравнения.

dat2 <- within(dat, {
  R <- ave(Value, Date, FUN=function(x) rank(x, na.last="keep"))
  E_P <- ave(R, Date, FUN=function(x) {
    findInterval(x, quantile(R, c(.2, .8), na.rm=TRUE))
  })
  E_P.fac <- factor(E_P, labels=c("worst", NA, "best"))
})
dat2 <- dat2[order(dat2$Date, dat2$E_P), ]  ## order by date and E_P

Выход:

dat2
#          Date Value E_P.fac E_P    R
# 1  2010-01-31     1   worst   0  1.5
# 16 2010-01-31     1   worst   0  1.5
# 2  2010-01-31     2    <NA>   1  3.0
# 3  2010-01-31     3    <NA>   1  4.0
# 4  2010-01-31     4    <NA>   1  5.0
# 5  2010-01-31     5    <NA>   1  6.0
# 6  2010-01-31     6    <NA>   1  7.0
# 7  2010-01-31     7    <NA>   1  8.0
# 8  2010-01-31     8    best   2  9.0
# 9  2010-01-31     9    best   2 10.0
# 15 2010-01-31    15    best   2 11.0
# 10 2010-01-31    NA    <NA>  NA   NA
# 11 2010-01-31    NA    <NA>  NA   NA
# 12 2010-01-31    NA    <NA>  NA   NA
# 13 2010-01-31    NA    <NA>  NA   NA
# 14 2010-01-31    NA    <NA>  NA   NA
# 17 2010-02-28     2   worst   0  1.0
# 18 2010-02-28     3   worst   0  2.0
# 19 2010-02-28     4    <NA>   1  3.0
# 20 2010-02-28     5    <NA>   1  4.0
# 21 2010-02-28     6    <NA>   1  5.0
# 22 2010-02-28     7    <NA>   1  6.0
# 23 2010-02-28     8    <NA>   1  7.0
# 24 2010-02-28     9    <NA>   1  8.0
# 30 2010-02-28    15    best   2  9.0
# 25 2010-02-28    NA    <NA>  NA   NA
# 26 2010-02-28    NA    <NA>  NA   NA
# 27 2010-02-28    NA    <NA>  NA   NA
# 28 2010-02-28    NA    <NA>  NA   NA
# 29 2010-02-28    NA    <NA>  NA   NA

Когда я проверяю квинтили столбца R ank, кажется, что он прав.

quantile(dat2$R, c(.2, .8), na.rm=TRUE)
# 20% 80% 
# 2.8 8.2 

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

with(dat2, table(Date, E_P.fac))
#             E_P.fac
# Date         worst <NA> best
#   2010-01-31     2    6    3
#   2010-02-28     2    6    1

Данные

dat <- structure(list(Date = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("2010-01-31", "2010-02-28"
), class = "factor"), Value = c(1, 2, 3, 4, 5, 6, 7, 8, 9, NA, 
NA, NA, NA, NA, 15, 1, 2, 3, 4, 5, 6, 7, 8, 9, NA, NA, NA, NA, 
NA, 15)), row.names = c(NA, -30L), class = "data.frame")
1 голос
/ 29 марта 2020

Возможно, вы могли бы использовать что-то подобное с quantile:

library(dplyr)

out <- CombData %>%
  group_by(Date) %>%
  mutate(S_P = case_when(Value <= quantile(Value, 0.2, na.rm = TRUE) ~ 'Worst', 
                     Value >= quantile(Value, 0.8, na.rm = TRUE) ~ 'Best')) 

Вы можете изменить значение quantile в соответствии со своими предпочтениями.


Чтобы получить Минимальное количество «Лучших» и «Худших» мы можем сделать:

out %>%
   count(Date, S_P) %>%
   na.omit() %>%
   ungroup()   %>%
   select(-Date)  %>%
   group_by(S_P) %>%
   top_n(-1, n)

#  S_P       n
#  <chr> <int>
#1 Best      2
#2 Worst     2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...