多元累计和

时间:2019-08-24 06:22:43

标签: r cumsum

假设一个人希望基于多元条件all(Z[i] <= x),为多元网格x上的所有i计算累积和。显然可以天真地实现

cSums <- numeric(nrow(x))
for(i in seq(nrow(x))){
   for(j in seq(nrow(Z))){
        if(all(Z[j, ] <= x[i, ]))
            cSums[i] <- cSums[i] + R[j] # <== R is a single vector to be summed
   }
}

大约在O((n*p)^2)左右,或者通过迭代子集来稍微加快

cSums <- numeric(nrow(x))
for(i in seq(nrow(x))){
    indx <- seq(nrow(Z))
    for(j in seq(ncol(Z))){
        indx <- indx[which(Z[indx, j] <= x[i, j])]
    }
    cSums[i] <- sum(R[indx])
}

但是,这仍然是最糟糕的情况,其速度与朴素的实现一样慢。如何改善这一点以获得更快的性能,同时又允许比较未定义的列数?

虚拟数据和可复制示例

var1 <- c(3,3,3,5,5,5,4,4,4,6)
var2 <- rep(seq(1,5), each = 2)
Z <- cbind(var1, var2)
x <- Z
R <- rep(1, nrow(x))
# Result using either method.
#[1] 2 2 3 4 6 6 5 5 6 10

2 个答案:

答案 0 :(得分:2)

outer是您的朋友,只是Vectorize您的比较。然后colSums会产生所需的结果。应该很快。

f <- Vectorize(function(k, l) all(Z[k, ] <= x[l, ]))

res <- colSums(outer(1:nrow(Z), 1:nrow(x), f))
res
# [1]  2  2  3  4  6  6  5  5  6 10

数据

x <- Z <- structure(c(3, 3, 3, 5, 5, 5, 4, 4, 4, 6, 1, 1, 2, 2, 3, 3, 4, 
4, 5, 5), .Dim = c(10L, 2L), .Dimnames = list(NULL, c("var1", 
"var2")))

答案 1 :(得分:1)

我们可以逐行使用apply并将每一行与其他每一行进行比较,并计算其中有多少满足标准。

apply(Z, 1, function(x) sum(rowSums(Z <= as.list(x)) == length(x)))
#[1]  2  2  3  4  6  6  5  5  6 10

也可以使用sapply + split

执行类似的方法
sapply(split(Z, seq_len(nrow(Z))), function(x) 
                sum(rowSums(Z <= as.list(x)) == length(x)))

数据

var1 <- c(3,3,3,5,5,5,4,4,4,6)
var2 <- rep(seq(1,5), each = 2)
Z <- data.frame(var1, var2)