Суммарные проценты в R

У меня есть следующий фрейм данных

d2
# A tibble: 10 x 2
  ID Count
<int> <dbl>
  1     1
  2     1
  3     1
  4     1
  5     1
  6     2
  7     2
  8     2
  9     3
 10     3

В нем указано, сколько счетчиков было у каждого человека (ID).

Я хотел бы рассчитать совокупный процент каждого подсчета: 1 - 50%, до 2: 80%, до 3: 100%. Я пытался

> d2 %>% mutate(cum = cumsum(Count)/sum(Count))
# A tibble: 10 x 3
  ID   Count     cum
 <int> <dbl>    <dbl>
   1     1   0.05882353
   2     1   0.11764706
   3     1   0.17647059
   4     1   0.23529412
   5     1   0.29411765
   6     2   0.41176471
   7     2   0.52941176
   8     2   0.64705882
   9     3   0.82352941
  10     3   1.00000000

но этот результат явно неверен, потому что я ожидал, что счет 1 будет соответствовать 50%, а не 29,4%.

Что здесь не так? Как мне получить правильный ответ?


person Omry Atia    schedule 29.03.2018    source источник
comment
Пожалуйста, покажите ожидаемый результат?   -  person akrun    schedule 29.03.2018
comment
Я не уверен, почему за вопрос проголосовали против, в то время как за ответы на вопрос проголосовали «за». Вероятно, следует добавить соответствующие комментарии для голосов против.   -  person MKR    schedule 29.03.2018
comment
В вопросе не проясняется, как должен выглядеть фактический результат, и не приводятся примеры данных в удобной для использования форме.   -  person LAP    schedule 29.03.2018
comment
Я не знаю, как должен выглядеть результат, как я уже писал выше, я знаю, чего ожидать от 50%, 80% и 100%   -  person Omry Atia    schedule 29.03.2018


Ответы (3)


Мы получаем count из 'Count', создаем 'Cum', взяв кумулятивную сумму 'n' и разделив ее на sum из 'n', затем right_join с исходными данными.

d2 %>% 
 count(Count) %>% 
 mutate(Cum = cumsum(n)/sum(n)) %>% 
 select(-n) %>% 
 right_join(d2) %>%
 select(names(d2), everything())
# A tibble: 10 x 3
#      ID Count   Cum
#   <int> <int> <dbl>
# 1     1     1 0.500
# 2     2     1 0.500
# 3     3     1 0.500
# 4     4     1 0.500
# 5     5     1 0.500
# 6     6     2 0.800
# 7     7     2 0.800
# 8     8     2 0.800
# 9     9     3 1.00 
#10    10     3 1.00 

Если нам нужен вывод, как указано в @LAP

d2 %>%
   mutate(Cum = row_number()/n())
#   ID Count Cum
#1   1     1 0.1
#2   2     1 0.2
#3   3     1 0.3
#4   4     1 0.4
#5   5     1 0.5
#6   6     2 0.6
#7   7     2 0.7
#8   8     2 0.8
#9   9     3 0.9
#10 10     3 1.0
person akrun    schedule 29.03.2018
comment
Результатом этого будет c (0.2000000 0.4000000 0.6000000 0.8000000 1.0000000 0.6666667 1.3333333 2.0000000 1.5000000 3.0000000), когда он должен заканчиваться на 1 и монотонно увеличиваться - person Omry Atia; 29.03.2018
comment
Op хочет подсчитать 0,1 для каждой строки, как при обработке каждой строки как 10% данных, независимо от значения Count. - person LAP; 29.03.2018
comment
Я почти уверен, что OP просто хочет что-то вроде 0.1, 0.2, 0.3, ..., 1.0 в качестве кумулятивного вектора. - person LAP; 29.03.2018

Это работает:

d2 %>%
  mutate(cum = cumsum(rep(1/n(), n())))

   ID Count cum
1   1     1 0.1
2   2     1 0.2
3   3     1 0.3
4   4     1 0.4
5   5     1 0.5
6   6     2 0.6
7   7     2 0.7
8   8     2 0.8
9   9     3 0.9
10 10     3 1.0
person LAP    schedule 29.03.2018
comment
В сообщении OP I would expect that the count of 1 would correspond to 50% rather than 29.4%. - person akrun; 29.03.2018
comment
Да, потому что в его попытке все 1 суммировались до 0.29 (строка 5 его вывода) вместо 0.5 (строка 5 моего вывода). - person LAP; 29.03.2018

Один из вариантов может быть таким:

library(dplyr)
d2 %>%
  group_by(Count) %>%
  summarise(proportion = n()) %>%
  mutate(Perc = cumsum(100*proportion/sum(proportion))) %>%
  select(-proportion)
# # A tibble: 3 x 2
# Count  Perc
# <int> <dbl>
# 1     1  50.0
# 2     2  80.0
# 3     3 100.0
person MKR    schedule 29.03.2018