我想计算应用于另一列的一组间隔[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
循环可以很容易;然而;我想避免这种方法并使用矢量化基础R
或dplyr
方法。
答案 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)))))