найти n% записей в переменной во фрейме данных - PullRequest
0 голосов
/ 16 февраля 2019

У меня есть данные во фрейме данных, в первом столбце - дата, а во втором столбце - индивидуальный вес.Вот пример из данных:

df <- data.frame(
  date = c("2019-01-01", "2019-01-01", "2019-01-01", "2019-01-01",
           "2019-01-01", "2019-01-01", "2019-01-01", "2019-01-01",
           "2019-01-01", "2019-01-01", "2019-01-02", "2019-01-02", "2019-01-02",
           "2019-01-02", "2019-01-02", "2019-01-02", "2019-01-02",
           "2019-01-02", "2019-01-02", "2019-01-02"),
  weight = c(2174.8, 2174.8, 2174.8, 8896.53, 8896.53, 2133.51, 2133.51,
             2892.32, 2892.32, 2892.32, 2892.32, 5287.78, 5287.78, 6674.03,
             6674.03, 6674.03, 6674.03, 6674.03, 5535.11, 5535.11)
)

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

Lowest 10%
10-20%
20-40%
40-60%
60-80%
80-90%
90-100%

The logic = (MinWeight + (MaxWeight-MinWeight)*X%)

Вот мой ожидаемый результат (я показываю только два столбца для диапазона%)

df %>% 
  group_by(date) %>%
  summarise(mean(weight), min(weight), max(weight))
   date       `mean(weight)` `min(weight)` `max(weight)` `Lowest 10%` `10-20%`
 2019-01-01          3726.         2134.         8897.    num records. num records.

Ответы [ 2 ]

0 голосов
/ 16 февраля 2019

Можно сделать так:

library(tidyverse)

df %>%
  group_by(date) %>%
  mutate(
    wrange = cut((weight - min(weight)) / (max(weight - min(weight))) * 100, 10,
                 labels = paste(
                   seq(0, 90, by = 10), 
                   paste0(seq(10, 100, by = 10), "%"), 
                   sep = '-')
                 )
    ) %>%
  left_join(
    x = summarise_at(., vars(weight), funs(mean, min, max)),
    y = count(., wrange) %>% complete(wrange, fill = list(n = 0)) %>% spread(wrange, n),
    by = 'date'
    ) %>%
  rename_at(vars(matches("mean|min|max")), funs(paste(., "(weight)", sep = "")))

Какие выходы:

#            date     mean(weight) min(weight) max(weight)  0-10%   10-20%  20-30%   30-40%  40-50%
#    1 2019-01-01     3726.144     2133.51     8896.53      5       3       0       0       0
#    2 2019-01-02     5790.825     2892.32     6674.03      1       0       0       0       0
#           50-60%  60-70%  70-80%  80-90%   90-100%
#           0       0       0       0        2
#           0       4       0       0        5

(я переформатировал вывод, чтобы показать все данные)

0 голосов
/ 16 февраля 2019

Проверьте это решение:

library(tidyverse)
library(wrapr)

df %>%
  group_by(date) %>%
  mutate(
    rn = row_number(),
    temp = weight - min(weight),
    temp = (temp / max(temp)) * 100,
    temp = cut(temp, seq(0, 100, 10), include.lowest = TRUE),
    temp = str_remove(temp, '\\(|\\[') %>%
      str_replace(',', '-') %>%
      str_replace('\\]', '%'),
    one = 1
  ) %>%
  spread(temp, one, fill = 0) %.>%
  left_join(
    summarise(.,
      `mean(weight)` = mean(weight),
      `min(weight)` = min(weight),
      `max(weight)` = max(weight)
    ),
    summarise_at(., vars(matches('\\d+-\\d+.')), sum)
  )

Вывод:

   date       `mean(weight)` `min(weight)` `max(weight)` `0-10%` `10-20%` `60-70%` `90-100%`
  <fct>               <dbl>         <dbl>         <dbl>   <dbl>    <dbl>    <dbl>     <dbl>
1 2019-01-01          3726.         2134.         8897.       5        3        0         2
2 2019-01-02          5791.         2892.         6674.       1        0        4         5
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...