使用group_by生成百分比并进行突变

时间:2019-05-16 18:40:35

标签: group-by dplyr plyr percentage

我正在处理一个数据集,该数据集包含每个predicted的预测标签(label)与真实标签(id)和一列,指示预测标签是否等于真实标签( match)。我想显示每个label正确预测的百分比与属于该标签的观察总数的对比。

作为示例,给定以下数据:

id <- c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
label <- c(6, 5, 1, 5, 4, 2, 3, 1, 6, 1)
predicted <- c(6, 5, 1, 3, 2, 2, 3, 1, 4, 4)
match <- c(1, 1, 1, 0, 0, 1, 1, 1, 0, 0)
dt <- data.frame(id, label, predicted, match)
head(dt)
  id label predicted match
1  1     6         6     1
2  2     5         5     1
3  3     1         1     1
4  4     5         3     0
5  5     4         2     0
6  6     2         2     1

如果我依次group_by(label)count(label, predicted),然后mutate(percent = sum(match == 1)/sum(n)),则应该获得这样的新分组数据帧

library(plyr)
library(dplyr)
dt %>% group_by(label) %>% dplyr::count(label, predicted) %>% mutate(percent = sum(match == 1)/sum(n))

dt
   id label predicted match percent
1   3     1         1     1    0.67
2   8     1         1     1    0.67
3  10     1         4     0    0.67
4   6     2         2     1    1.00
5   7     3         3     1    1.00
6   5     4         2     0    0.00
7   4     5         3     0    0.50
8   2     5         5     1    0.50
9   9     6         4     0    0.50
10  1     6         6     1    0.50

但是,我的代码代替了下面的输出

dt
# A tibble: 6 x 4
# Groups:   label [5]
  label predicted     n percent
  <dbl>     <dbl> <int>   <dbl>
1  1.00      1.00     2   0.600
2  1.00      4.00     1   0.600
3  2.00      2.00     1   0.600
4  3.00      3.00     1   0.600
5  4.00      2.00     1   0.600
6  5.00      3.00     1   0.600

它计算了“全部” label的正确预测的百分比(因此,全部等于0.600),而不是每个label都这样做。我应该如何修改代码以获得所需的输出?

1 个答案:

答案 0 :(得分:1)

我无法使用您共享的代码来复制您的输出。我认为以下方法可以满足您的要求(我使用total作为变量名而不是n):

dt %>% 
  arrange(label) %>% 
  group_by(label) %>% 
  mutate(total = n(), 
         percent = sum(match == 1) / total)
# A tibble: 10 x 6
# Groups:   label [6]
      id label predicted match total percent
   <dbl> <dbl>     <dbl> <dbl> <int>   <dbl>
 1     3     1         1     1     3   0.667
 2     8     1         1     1     3   0.667
 3    10     1         4     0     3   0.667
 4     6     2         2     1     1   1    
 5     7     3         3     1     1   1    
 6     5     4         2     0     1   0    
 7     2     5         5     1     2   0.5  
 8     4     5         3     0     2   0.5  
 9     1     6         6     1     2   0.5  
10     9     6         4     0     2   0.5