为数据框中的多个列创建分布表

时间:2017-10-24 15:29:36

标签: r dplyr

我有以下虚拟数据:

a <- c(4,8,8,2,8,4,2,16)
b <- c(16,32,2,1,0.5,64,2,1)
c <- c(0.25,0.25,0.12,1,4,8,16,16)

df<-data.frame(a,b,c,stringsAsFactors = FALSE)

(注意:我想要执行此操作的数据框还有很多其他列,这与此特定分析无关)

我想结束这样的事情:

   n  0.12  0.25   0.5   1    2   4    8    16   32   64  
a  8  0     0      0     0    25  25   37.5 12.5 0    0
b  8  0     0      12.5  25   25  0    0    12.5 12.5 12.5
c  8  12.5  25     0     12.5 0   12.5 12.5 25   0    0

其中每个对应列的数据框中的总行数为n,以及下一列中每个值的百分比分布(每行的总和,从列&#34; 0.12&#34;到&#34; 64&#34;等于100%)

我已经成功地一次为一列做了这个:

library(dplyr)    

test <- df %>%
    count(a) %>%
    mutate(perc = n/sum(n)*100) %>%
    select(-n) %>%
    spread(a, perc)

然而,有了这个,我失去了&#34; n&#34;列。

我已经尝试对我想要包含的所有列使用count(),但这会计算与正在计算的另一个相关的每个观察结果,从而产生比我正在寻找的更大的表。我还想保留所有列,无论它们是0。

2 个答案:

答案 0 :(得分:2)

您也可以尝试:

df %>% 
  gather() %>% 
  group_by(key) %>% 
  mutate(n1=n()) %>% 
  count(value, n1) %>% 
  mutate(perc = n/sum(n)*100) %>% 
  select(-n, n=n1) %>% 
  spread(value, perc, fill = 0) 
# A tibble: 3 x 12
# Groups:   key [3]
    key    n  `0.12` `0.25` `0.5`   `1`   `2`   `4`   `8`  `16`  `32`  `64`
* <chr> <int>  <dbl>  <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1     a     8    0.0      0   0.0   0.0    25  25.0  37.5  12.5   0.0   0.0
2     b     8    0.0      0  12.5  25.0    25   0.0   0.0  12.5  12.5  12.5
3     c     8   12.5     25   0.0  12.5     0  12.5  12.5  25.0   0.0   0.0

答案 1 :(得分:0)

我们可以使用map

library(tidyverse)
df %>%
    map(~tibble(.x) %>%
         count(.x) %>% 
         mutate(perc = n/sum(n)*100) %>% 
         select(-n) %>% 
         spread(.x, perc)) %>%
     bind_rows %>% 
     bind_cols(gather(df) %>% 
                   count(key), .) %>%
     mutate_if(is.numeric, funs(replace(., is.na(.), 0))) 
# A tibble: 3 x 12
#    key     n   `2`   `4`   `8`  `16` `0.5`   `1`  `32`  `64` `0.12` `0.25`
#  <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>  <dbl>  <dbl>
#1     a     8    25  25.0  37.5  12.5   0.0   0.0   0.0   0.0    0.0      0
#2     b     8    25   0.0   0.0  12.5  12.5  25.0  12.5  12.5    0.0      0
#3     c     8     0  12.5  12.5  25.0   0.0  12.5   0.0   0.0   12.5     25