区间为

时间:2016-01-08 02:37:49

标签: r dplyr

我想计算应用于另一列的一组间隔[n, +∞)(即≥ n)的数据框列的条件和。在下面的示例数据中,区间应用于列a,并且列b中的值有条件地求和。对于[0, +∞),所有列a值均为≥ 0,因此b_sum是所有值的总和。对于[3, +∞),只有一条记录为≥ 3,因此b_sum为500。

输入数据

  a    b          
1.1  100          
2.3  150          
0.1   20          
0.5   80          
3.3  500          
1.6  200
1.1  180

期望的结果

n  b_sum
0   1230
1   1130
2    650
3    500
4      0

我确信使用for循环可以很容易;然而;我想避免这种方法并使用矢量化基础Rdplyr方法。

4 个答案:

答案 0 :(得分:5)

矢量化解决方案

df <- df[order(df$a), ] # sort by "a" column
ind <- findInterval(0:4, df$a) + 1 
sum(df$b) - cumsum(c(0,  df$b))[ind]
#[1] 1230 1130  650  500    0

答案 1 :(得分:4)

我们可以使用vapply

 n <- trunc(min(df1$a)) : ceiling(max(df1$a))


 b_sum <- vapply(n, function(i) sum(df1$b[!is.na(cut(df1$a,
                     breaks=c(i, Inf)))]), 0)
 b_sum
#[1] 1230 1130  650  500    0
data.frame(n, b_sum)

我们也不需要cut

vapply(n, function(i) sum(df1$b[df1$a>i]), 0)
#[1] 1230 1130  650  500    0

答案 2 :(得分:4)

布尔数学。将矢量乘以逻辑条件,变为0/1

 sapply(0:4, function(n) { sum( (sub("\\..+$", "", inp$a) >= n )*inp$b ) } )
#[1] 1230 1130  650  500    0

data.frame( n=0:4, 
            b_sum= sapply(0:4, function(n) sum( sub("\\..+$", "", inp$a) >= n)*inp$b) )

答案 3 :(得分:2)

另一种可能性:

data.frame(n = 0:4, b_sum = with(df, sum(b) - c(0, cumsum(tapply(b, floor(a), sum)))))