2014-11-05 6 views
7

Chcę wstawić zestaw n wartości wyrażonych jako wektor do odpowiedniego zestawu lokalizacji w macierzy. Aplikacja świata rzeczywistego polega na wstawieniu zestawu wartości temperatury powierzchni morza na obraz regionu, który jest reprezentowany jako siatka z wymiarem nrow x ncol> n, dla którego zidentyfikowałem n pikseli wody, które powinny otrzymać wartości temperatury . Problemem, który napotkam, jest to, że wartości temperatury są uporządkowane tak, jakby były z matrycy kolumna-dur, a nie z rzędowej-głównej kolejności używanej do indeksowania siatki R.Jak mogę wstawić wartości z wektora do macierzy przy użyciu kolumny-głównej kolejności?

Oto zabawny przykład tego, co mam na myśli.

> grid <- matrix(0,4,4) 
> grid      # define the base grid 
    [,1] [,2] [,3] [,4] 
[1,] 0 0 0 0 
[2,] 0 0 0 0 
[3,] 0 0 0 0 
[4,] 0 0 0 0 

> temps <- c(9,9,9,9,9)  # we have 5 temperature values 
> locs <- c(2,3,4,6,7)  # locations in the base grid that are water 

> grid[locs] <- temps  # not really what I want - substitution in row-major order 
> grid 
    [,1] [,2] [,3] [,4] 
[1,] 0 0 0 0 
[2,] 9 9 0 0 
[3,] 9 9 0 0 
[4,] 9 0 0 0 

pożądany wynik byłby raczej:

 [,1] [,2] [,3] [,4] 
[1,] 0 9 9 9 
[2,] 0 9 9 0 
[3,] 0 0 0 0 
[4,] 0 0 0 0 

Przypuszczam, że mógłbym grać z transpozycji siatkę, robi podstawienie a następnie transpozycji go z powrotem, ale ja myślę, że byłoby lepiej sposób podejścia do tego problemu.

Odpowiedz

6

Oto kilka opcji, z których każda działa na matrycach arbitralnego wymiaru:


arrayIndByRow <- function(ind, dim) { 
    arrayInd(ind, rev(dim))[,2:1] 
} 

grid[arrayIndByRow(locs, dim(grid))] <- temps 
grid 
#  [,1] [,2] [,3] [,4] 
# [1,] 0 9 9 9 
# [2,] 0 9 9 0 
# [3,] 0 0 0 0 
# [4,] 0 0 0 0 

f <- function(ind, dim) { 
    nr <- dim[1] 
    nc <- dim[2] 
    ii <- ind - 1 
    ((ii %/% nc) + 1) + nr*(ii %% nc) 
} 

grid[f(locs, dim(grid))] <- 1:5 
grid 
#  [,1] [,2] [,3] [,4] 
# [1,] 0 1 2 3 
# [2,] 0 4 5 0 
# [3,] 0 0 0 0 
# [4,] 0 0 0 0 
+0

Jestem prawie pewien, że twoja druga opcja działa tylko dla macierzy kwadratowych (ponieważ jest taka sama jak moja poniżej).) Na przykład, biorąc pod uwagę macierz 4 na 5, 2 powinno iść do 6, ale z powyższą funkcją, ' f (2, c (4,5)) == 5'. – jed

+0

@jed - Nie, to nie jest poprawne. W przypadku macierzy 4x5, 2 * powinno * odwzorować do 5. (Odlicza cztery elementy w pierwszej kolumnie, a następnie dociera do góry w górnej części drugiej kolumny, gdy osiągnie piąty element). Wypróbuj sam, aby zobaczyć, że jest to poprawne, z 'siatką <- macierz (0, nr = 4, nc = 5); grid [f (2, dim (grid))] <- 99; siatka ". Przykro mi też, że nie widziałem i po prostu edytuję twoją odpowiedź, kiedy tu wróciłem, aby dodać moje własne podobne "f" - zrobiłem +1 twojemu, gdy zauważyłem to kilka godzin temu! –

+0

Ach tak, szedłem w niewłaściwy sposób. Tak jak w 6 powinno przejść do 2, co dzieje się w twojej funkcji! – jed

3

Jednym ze sposobów, aby to zrobić, jest utworzenie nowej macierzy z wymaganymi danymi, określając byrow=TRUE po jej utworzeniu. Aby to zrobić, trzeba utworzyć pośredniego wektora do przechowywania i modyfikacji danych o grid:

grid <- matrix(rep(0,16),ncol=4) 
## 
temps <- c(9,9,9,9,9)  
locs <- c(2,3,4,6,7)  
## 
#vgrid <- as.numeric(grid) 
vgrid <- c(grid) 
vgrid[locs] <- temps 
## 
> matrix(vgrid,ncol=ncol(grid),byrow=TRUE) 
    [,1] [,2] [,3] [,4] 
[1,] 0 9 9 9 
[2,] 0 9 9 0 
[3,] 0 0 0 0 
[4,] 0 0 0 0 
+0

prostu ciekawi, dlaczego 'as.numeric (siatka) '? 'grid' jest już numeryczne. Możesz użyć 'c (grid)', aby zwinąć matrycę –

+0

Ahh dobry telefon, dziękuję. – nrussell

3

Jeśli masz macierzy kwadratowej, można napisać niewiele funkcji modulo, który zastępuje swoje numery z właociwe:

new_num <- function(x,num_rows){ 
    x = x - 1 
    row <- x %/% num_rows 
    column <- x %% num_rows 
    newnum <- column * num_rows + row + 1 
    return(newnum) 
} 

temps <- c(9,9,9,9,9)  
locs <- c(2,3,4,6,7) 

new_locs <- new_num(locs,4) 

M <- matrix(0,4,4) 
M[new_locs] <- temps 

Można to zrobić również z macierzą inną niż kwadratowa, jest tylko trochę trudniejsza.

3

Możesz pracować z indeksami. Najpierw wykonujemy sekwencję o długości macierzy według liczby kolumn. Następnie dodajemy kolejno 1 do sekwencji. Robimy to dla liczby rzędów. Następnie podsekcja tego wektora dla wektora położenia da nam lokalizację w macierzy.

x <- seq(1, length(grid), ncol(grid)) 
grid[sapply(0:(nrow(grid)-1), "+", x)[locs]] <- temps 
grid 

#  [,1] [,2] [,3] [,4] 
# [1,] 0 9 9 9 
# [2,] 0 9 9 0 
# [3,] 0 0 0 0 
# [4,] 0 0 0 0 
Powiązane problemy