Kamil Bęczyński

Kamil Bęczyński R, SAS, analizy

Temat: Agregowanie wektora

Przykład w=c(1,2,3,4,5,0) chciałbym znaleźć funkcję przy użyciu której dla wartości 2 otrzymam wynik c(3,7,5), a dla wartości 3 c(6,9), czyli sumę liczb w kolejnych grupach, w grupach o długości odpowiednio dwóch i trzech elementów. Chcę sprawdzić czy funkcja ta będzie szybsza od mojego kodu.

Pozdrawiam
Wojciech Sobala

Wojciech Sobala Redaktor
statystyczny,
biostatystyk,
Instytut Medycyny
Pr...

Temat: Agregowanie wektora

Standardowe podejście z funkcją split i lapply:

fun_split <- function(x,k){
n <- length(x)
a <- n %/% k
i <- rep(seq.int(a + 1),c(rep(k, a),n %% k))
return(unlist(lapply(split(x,i),sum),use.names=FALSE))
}

Wykorzystanie colSums:

fun_mat <- function(x,k){
if(length(x) %% k > 0) x <- c(x,rep(0,k - length(x) %% k))
m <- matrix(x,nrow=k)
return(colSums(m))
}
Michał Bojanowski

Michał Bojanowski socjolog, analityk

Temat: Agregowanie wektora

Jeszcze inny wariant:

f <- function(x, k)
{
a <- length(x) %/% k
g <- rep(seq.int(a+1), each=k, length=length(x))
tapply(x, g, sum)
}
Kamil Bęczyński

Kamil Bęczyński R, SAS, analizy

Temat: Agregowanie wektora

Dzięki za kod, szukałem po prostu wbudowanej funkcji, mając nadzieję, że taka istnieje:)

ps.wydaje mi się, że fun_mat jest 15 razy szybsza od fun_splitKamil Bęczyński edytował(a) ten post dnia 30.08.11 o godzinie 19:52
Wojciech Sobala

Wojciech Sobala Redaktor
statystyczny,
biostatystyk,
Instytut Medycyny
Pr...

Temat: Agregowanie wektora

Dwie dodatkowe implementacje napisane w stylu C i Lispa.

fun_c = function(x,k){
n0 = seq.int(1,length(x),by=k)
n1 = n0 + as.integer(k)
n1[length(n1)] = length(x)
w = vector(mode="numeric",length=length(n0))
for(i in seq.int(length(w))){
w[i] = sum(x[n0[i]:n1[i]])
}
return(w)
}

require(compiler)
cfun_c <- cmpfun(fun_c)

assign("fun_lisp",function(x,k) {
return(unlist(Map(function(x) sum(x),
split(x, gl((length(x) %/% k) + 1,k,length(x)))),
use.names=FALSE))
})



Wyślij zaproszenie do