2013-06-02 7 views
5

voglio andare da qualcosa di simile:blocco per blocco somma degli elementi di matrice

1> a = matrix(c(1,4,2,5,2,5,2,1,4,4,3,2,1,6,7,4),4) 
1> a 
    [,1] [,2] [,3] [,4] 
[1,] 1 2 4 1 
[2,] 4 5 4 6 
[3,] 2 2 3 7 
[4,] 5 1 2 4 

Per qualcosa di simile:

 [,1] [,2] 
[1,] 12 15 
[2,] 10 16 

... senza usare per-loop, plyr, o in altro modo, senza looping. Possibile? Sto cercando di ridurre un set di dati geografici lat/long da 5 minuti d'arco a mezzo grado, e ho una griglia ascii. Una piccola funzione in cui specifichi il blockize sarebbe grandiosa. Ho centinaia di questi file, quindi le cose che mi permettono di farlo rapidamente senza parallelizzazione/supercomputer sarebbero molto apprezzate.

risposta

7

È possibile utilizzare la moltiplicazione della matrice per questo.

# Computation matrix: 

mat <- function(n, r) { 
    suppressWarnings(matrix(c(rep(1, r), rep(0, n)), n, n/r)) 
} 

esempio Square-matrix, utilizza una matrice e la sua trasposizione su ciascun lato della a: esempio

# Reduce a 4x4 matrix by a factor of 2: 

x <- mat(4, 2) 
x 
##  [,1] [,2] 
## [1,] 1 0 
## [2,] 1 0 
## [3,] 0 1 
## [4,] 0 1 

t(x) %*% a %*% x 
##  [,1] [,2] 
## [1,] 12 15 
## [2,] 10 16 

non quadrati:

b <- matrix(1:24, 4 ,6) 
t(mat(4, 2)) %*% b %*% mat(6, 2) 
##  [,1] [,2] [,3] 
## [1,] 14 46 78 
## [2,] 22 54 86 
+0

esattamente il tipo di cosa che mi stava cercando grazie, grazie! la mia matrice non è quadrata, ma metà è. –

0

Immagino che questo possa aiutarti, ma continua a usare tranquillamente, che può essere considerato uno strumento loop-ish.

a <- matrix(c(1,4,2,5,2,5,2,1,4,4,3,2,1,6,7,4),4) 
block.step <- 2 
res <- sapply(seq(1, nrow(a), by=block.step), function(x) 
    sapply(seq(1, nrow(a), by=block.step), function(y) 
     sum(a[x:(x+block.step-1), y:(y+block.step-1)]) 
    ) 
) 
res 

È comunque utile?

4
tapply(a, list((row(a) + 1L) %/% 2L, (col(a) + 1L) %/% 2L), sum) 
# 1 2 
# 1 12 15 
# 2 10 16 

Ho usato 1L e 2L invece di 1 e 2 così gli indici rimangono interi (al contrario di numerici) e dovrebbe correre più veloce in questo modo.