2013-06-02 16 views
5

Chcę iść z czymś tak:wierszami suma elementów macierzy

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 

Aby coś takiego:

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

... bez użycia for-pętle, plyr, lub w inny sposób bez zapętlanie. Możliwy? Próbuję zmniejszyć geograficzny zestaw danych długości/długości z 5 minut do półtora i mam siatkę ASCII. Mała funkcja, w której określam rozmiar bloku, byłaby świetna. Mam setki takich plików, więc rzeczy, które pozwalają mi to robić szybko bez równoległości/superkomputerów, byłyby mile widziane.

Odpowiedz

7

Możesz użyć do tego mnożenia macierzy.

# Computation matrix: 

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

przykład Square-matrix, wykorzystuje matrycę i jej transpozycję na każdej stronie a:

# 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-kwadrat przykład:

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

dokładnie coś takiego szukałem za, dzięki! moja macierz nie jest kwadratowa, ale połowa z niej jest. –

0

Myślę, że to może ci pomóc, ale nadal używa sapply, które można uznać za narzędzie pętli.

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 

Czy jest to w jakiś sposób pomocne?

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

użyłem 1L i 2L zamiast 1 i 2 więc indeksy pozostają liczb całkowitych (w przeciwieństwie do numerycznych) i powinien działać szybciej w ten sposób.