在data.table中按组返回组频率,满足条件的值的计数和比率

时间:2017-06-20 17:55:55

标签: r data.table dplyr

鉴于下面的data.table,我如何获得所需的结果? ' grpFreq'列包含每个' grp'的计数。在原始的data.table中,' posCnt'列包含' val'中的正数计数。对于每个群体,以及'比率'列是posCnt / grpFreq。

library( data.table )

DT <- data.table( grp = c(1,2,5,5,5,5,3,4,4,4), val = c(-1,0,1,1,-1,1,1,-1,-1,1) )
DT

    grp val
 1:   1  -1
 2:   2   0
 3:   5   1
 4:   5   1
 5:   5  -1
 6:   5   1
 7:   3   1
 8:   4  -1
 9:   4  -1
10:   4   1

达到预期的结果:

# grp   grpFreq posCnt  ratio
# 1     1       0       0
# 2     1       0       0
# 3     1       1       1
# 4     3       1       0.33
# 5     4       3       0.75

以下尝试让我参与其中。首先,值的计数>来自&#39; val&#39;列位于此处最右侧的列中(不需要&#39; -1&#39;和&#39; 0&#39;列):

dcast(DT, grp~val, length)

   grp -1 0 1
1:   1  1 0 0
2:   2  0 1 0
3:   3  0 0 1
4:   4  2 0 1
5:   5  1 0 3

其次,这会得到每个&#39; grp&#39;的频率计数,但不是与上面相同的形式:

library(dplyr)
DT %>%
    group_by(grp) %>%
    mutate(count = n())

     grp   val count
   (dbl) (dbl) (int)
1      1    -1     1
2      2     0     1
3      5     1     4
4      5     1     4
5      5    -1     4
6      5     1     4
7      3     1     1
8      4    -1     3
9      4    -1     3
10     4     1     3

有什么想法吗?非常感谢!!

2 个答案:

答案 0 :(得分:2)

data.table,您可以

DT[order(grp), .(grpFreq=.N, posCnt=sum(val > 0), ratio=sum(val > 0) / .N), by=grp]

在一次通话中或更好地使用链和:=

DT[order(grp), .(grpFreq=.N, posCnt=sum(val > 0)), by=grp][, ratio := posCnt / grpFreq][]

第二种方法可能更可取,因为它减少了计算次数,并且:=的赋值具有内存效率。第二次通话结束时[]在实践中不是必需的,但会告诉data.table将结果打印到屏幕上。

两者都返回

   grp grpFreq posCnt     ratio
1:   1       1      0 0.0000000
2:   2       1      0 0.0000000
3:   3       1      1 1.0000000
4:   4       3      1 0.3333333
5:   5       4      3 0.7500000

答案 1 :(得分:1)

DT <- data.table( grp = c(1,2,5,5,5,5,3,4,4,4), val = c(-1,0,1,1,-1,1,1,-1,-1,1) )

DT %>%
  group_by(grp) %>%
  summarize(grpFreq  = length(grp), 
            posCnt = sum(val > 0)) %>%
  mutate(ratio = posCnt/grpFreq)

# A tibble: 5 × 4
    grp grpFreq posCnt     ratio
  <dbl>   <int>  <int>     <dbl>
1     1       1      0 0.0000000
2     2       1      0 0.0000000
3     3       1      1 1.0000000
4     4       3      1 0.3333333
5     5       4      3 0.7500000