2012-02-24 3 views
2

Скажем, у меня есть матрица значенийR: Раскол матрица на произвольное число блоков

set.seed(1) 
    A <- matrix(runif(25),ncol=5) 

Я хотел бы вычислить некоторые статистические данные по примерно квадратных кварталов в пределах этой матрицы примерно одинакового размера. Любой из этих видов продукции будет делать:

N1 <- matrix(c(rep(c("A","A","B","B","B"),2),rep(c("C","C","D","D","D"),3)),ncol=5) 
    N2 <- matrix(c(rep(c("A","A","A","B","B"),3),rep(c("C","C","D","D","D"),2)),ncol=5) 
    N1 
     [,1] [,2] [,3] [,4] [,5] 
    [1,] "A" "A" "C" "C" "C" 
    [2,] "A" "A" "C" "C" "C" 
    [3,] "B" "B" "D" "D" "D" 
    [4,] "B" "B" "D" "D" "D" 
    [5,] "B" "B" "D" "D" "D" 

    N2 
     [,1] [,2] [,3] [,4] [,5] 
    [1,] "A" "A" "A" "C" "C" 
    [2,] "A" "A" "A" "C" "C" 
    [3,] "A" "A" "A" "D" "D" 
    [4,] "B" "B" "B" "D" "D" 
    [5,] "B" "B" "B" "D" "D" 

других приближения также хорошо, так как я всегда могу повернуть матрицу. Тогда я могу использовать эти матрицы окрестностей вычислить статистику, используя tapply(), как это:

tapply(A,N1,mean) 
      A   B   C   D 
    0.6201744 0.5057402 0.4574495 0.5594227 

То, что я хочу, это функция, которая может сделать мне матрицу произвольного размера с произвольным числом блоков типа окрестностей как N1 или N2. Я с трудом пытаюсь понять, как такая функция будет иметь дело с ситуациями, когда желаемое количество блоков не является даже квадратами. N1 и N2 имеют 4 пригороды, но сказать, что я хотел 5 для какого-то выходного что-то вроде этого:

N3 <- matrix(c("A","A","B","B","B","A","A","C","C","C","D","D","C","C","C", 
      "D","D","E","E","E","D","D","E","E","E"),ncol=5) 
     [,1] [,2] [,3] [,4] [,5] 
    [1,] "A" "A" "D" "D" "D" 
    [2,] "A" "A" "D" "D" "D" 
    [3,] "B" "C" "C" "E" "E" 
    [4,] "B" "C" "C" "E" "E" 
    [5,] "B" "C" "C" "E" "E" 

Кто-нибудь знает о существующей функции, которые могут сделать этот вид раскола, или есть какие-либо идеи о том, как сделать один ? Спасибо!

[[Edit]] Моя последняя функция, принимая во внимание рекомендации Винсента:

DecideBLocks <- function(A,nhoods){ 
     nc <- ncol(A) 
     nr <- nrow(A) 
     nhood_side <- floor(sqrt((nc*nr)/nhoods)) 
     Neighborhoods <- matrix(paste(ceiling(col(A)/nhood_side), ceiling(row(A)/nhood_side), sep="-"), nc=ncol(A)) 
     nhoods.out <- length(unique(c(Neighborhoods))) 
     if (nhoods.out != nhoods){ 
      cat(nhoods.out,"neighborhoods created.\nThese were on average",nhood_side,"by",nhood_side,"cells\nit's a different number than that stated the function tries to round things to square neighborhoods\n") 
     } 
     return(Neighborhoods) 
    } 
    A <- matrix(rnorm(120),12) 
    B <- DecideBLocks(A,13) 

ответ

2

Вы можете попробовать сыграть с функциями row и col: они уменьшают проблему к 1-одномерной. Ниже определяются блоки размером не более 2 * 2.

matrix( 
    paste(
    ceiling(col(A)/2), 
    ceiling(row(A)/2), 
    sep="-"), 
    nc=ncol(A) 
) 
+0

Спасибо, Винсент, я думаю, что смогу получить то, что мне нужно, –

1

Вы можете выбрать bdeep (строка-спецификации) и bwide (со-спецификации) параметров вблизи центра youree размер матрицы любым способом, который вам нравится, и использовать эту простую функцию для построения вашей матрицы. Пока bwide и bdeep равны, и nrow == ncol, вы должны получить квадратные подматрицы.

mkblk <- function(bwide, bdeep, nrow, ncol){ 
    bstr1 <- c(rep("A", bdeep), rep("B", nrow-bdeep)) 
    bstr2 <- c(rep("C", bdeep), rep("D", nrow-bdeep)) 
    matrix(c(rep(bstr1, bwide), rep(bstr2, ncol-bwide)), ncol=ncol, nrow=nrow)} 
mkblk(2,2,5,5) 

    [,1] [,2] [,3] [,4] [,5] 
[1,] "A" "A" "C" "C" "C" 
[2,] "A" "A" "C" "C" "C" 
[3,] "B" "B" "D" "D" "D" 
[4,] "B" "B" "D" "D" "D" 
[5,] "B" "B" "D" "D" "D" 

#Test of your strategy 
tapply(A, mkblk(2,2,5,5), mean) 
     A   B   C   D 
0.6201744 0.5057402 0.4574495 0.5594227 
+0

Спасибо, DWin, Винсент немного поскользнулся, но здесь есть хорошие идеи. –

Смежные вопросы