R - 计算箱中特定值的数量

时间:2015-08-13 06:49:35

标签: r

我有一个数据框(df),如下所示:

Value <- c(1,1,0,2,1,3,4,0,0,1,2,0,3,0,4,5,2,3,0,6)
Sl <- c(1:20)
df <- data.frame(Sl,Value)    

> df
   Sl Value
1   1     1
2   2     1
3   3     0
4   4     2
5   5     1
6   6     3
7   7     4
8   8     0
9   9     0
10 10     1
11 11     2
12 12     0
13 13     3
14 14     0
15 15     4
16 16     5
17 17     2
18 18     3
19 19     0
20 20     6

我想在df中创建4个分箱,并在单独的数据框中计算Value=0分组Sl值的出现次数,如下所示:

Bin Count
1   1
2   2
3   2
4   1

我尝试使用tablecut来创建所需数据框,但不清楚我将如何指定df$Value以及找到0的逻辑在这里

df.4.cut <- as.data.frame(table(cut(df$Sl, breaks=seq(1,20, by=5))))

4 个答案:

答案 0 :(得分:3)

使用您的df

tapply(df$Value, cut(df$Sl, 4), function(x) sum(x==0))

给出

> tapply(df$Value, cut(df$Sl, 4), function(x) sum(x==0))
(0.981,5.75]  (5.75,10.5]  (10.5,15.2]    (15.2,20] 
           1            2            2            1 

cut中,您可以根据需要指定中断数或中断数,并且逻辑位于tapply

中的函数定义中

答案 1 :(得分:2)

或者使用data.table,我们会转换&#39; data.frame&#39;到&#39; data.table&#39; (setDT(df)),使用cut输出作为分组变量,我们得到sum的&#39;值&#39;这是&#39; 0&#39; 0 (!Value)。通过否定(!),列将被转换为逻辑向量,即TRUE表示0,FALSE表示所有其他值不等于0。

library(data.table)
setDT(df)[,sum(!Value) , .(gr=cut(Sl,breaks=seq(0,20, 5)))]
#        gr V1
#1:   (0,5]  1
#2:  (5,10]  2
#3: (10,15]  2
#4: (15,20]  1

答案 2 :(得分:2)

您的问题使用table(),但缺少第二个参数。需要生成列联表。您可以通过以下方式找到每个箱柜的数量:

table(cut(df$Sl,4),df$Value)

             0 1 2 3 4 5 6
(0.981,5.75] 1 3 1 0 0 0 0
(5.75,10.5]  2 1 0 1 1 0 0
(10.5,15.2]  2 0 1 1 1 0 0
(15.2,20]    1 0 1 1 0 1 1

每个垃圾箱的Value == 0计数:

table(cut(df$Sl,4),df$Value)[,"0"] 

(0.981,5.75]  (5.75,10.5]  (10.5,15.2]    (15.2,20] 
           1            2            2            1 

答案 3 :(得分:1)

使用sqldf的更复杂的方式:

首先,我们创建一个定义箱和范围(最小和最大)的表:

bins <- data.frame(id = c(1, 2, 3, 4), 
                   bins = c("(0,5]", "(5,10]", "(10,15]", "(15,20]"),
                   min = c(0, 6, 11, 16), 
                   max = c(5, 10, 15, 20))

   id    bins min max
1  1   (0,5]   0   5
2  2  (5,10]   6  10
3  3 (10,15]  11  15
4  4 (15,20]  16  20

然后,我们使用以下查询,使用sl将每个BETWEEN分隔到其各自的组中,Value等于0。

library(sqldf)
sqldf("SELECT bins, COUNT(Value) AS freq FROM df, bins
      WHERE (((sl) BETWEEN [min] AND [max]) AND Value = 0) 
      GROUP BY bins
      ORDER BY id")

输出:

     bins freq
1   (0,5]    1
2  (5,10]    2
3 (10,15]    2
4 (15,20]    1

使用cut简化mts建议的bin构造的另一种方法,提取因子的levels

bins <- data.frame(id = 1:4, 
                   bins = levels(cut(Sl, breaks = seq(0, 20, 5))),
                   min = seq(1, 20, 5), 
                   max = seq(5, 20, 5))