Как суммировать процентное распределение кластеров по группам?

#r #data-manipulation

#r #манипулирование данными

Вопрос:

Рассмотрим этот фрейм данных:

 set.seed(123)
data <- data.frame(Loc = rep(letters[1:20], each = 5),
                  ID = 1:200,
                  cluster = sample(4, 200, replace=T))
 

Loc это группирующая переменная для ID s, и каждая ID из них была присвоена a cluster на основе некоторого атрибута.

Я хочу создать data.frame, который показывает, какой процент каждого Loc из них был назначен каждому из 4 cluster s:

 Loc   1     2     3     4    
a     ...  ...   ...   ...    
b     ...  ...   ...   ...     
c     ...  ...   ...   ...     
...
 

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

 Loc   1     2     3     4    total
a     ...  ...   ...   ...    ...
b     ...  ...   ...   ...    ...
c     ...  ...   ...   ...    ...
...
 

Каков наилучший способ сделать это?

Ответ №1:

Мы можем использовать tidyverse :

 library(tidyverse)

dat %>%
  count(Loc, cluster) %>%
  group_by(Loc) %>%
  # calculate percent within Loc
  mutate(n = n / sum(n)) %>%
  # long to wide -> clusters now columns 
  pivot_wider(names_from = cluster, values_from = n) %>%
  # add count by Loc
  inner_join(count(dat, Loc, name = "Total"))

 #   Loc     `1`   `2`   `3`   `4` Total
 # 1 a       0.2   0.2   0.4   0.2    10
 # 2 b       0.2   0.4   0.3   0.1    10
 # 3 c       0.2   0.4   0.1   0.3    10
 # ...
 

Ответ №2:

В базе R вы могли бы сделать:

 res <- with(data, table(Loc, cluster))
data.frame(as.data.frame.matrix(prop.table(res, 1)), 
           total=rowSums(res), check.names = FALSE)
#>     1   2   3   4 total
#> a 0.2 0.2 0.4 0.2    10
#> b 0.2 0.4 0.3 0.1    10
#> c 0.2 0.4 0.1 0.3    10
#> d 0.1 0.3 0.4 0.2    10
#> e 0.5 0.0 0.3 0.2    10
#> f 0.2 0.4 0.3 0.1    10
#> g 0.1 0.5 0.2 0.2    10
#> h 0.2 0.3 0.3 0.2    10
#> i 0.2 0.3 0.2 0.3    10
#> j 0.2 0.4 0.3 0.1    10
#> k 0.3 0.1 0.4 0.2    10
#> l 0.3 0.2 0.4 0.1    10
#> m 0.2 0.3 0.3 0.2    10
#> n 0.4 0.2 0.3 0.1    10
#> o 0.3 0.2 0.2 0.3    10
#> p 0.0 0.2 0.3 0.5    10
#> q 0.2 0.3 0.3 0.2    10
#> r 0.2 0.4 0.3 0.1    10
#> s 0.2 0.3 0.1 0.4    10
#> t 0.3 0.1 0.4 0.2    10