2014-11-05 14 views
7

Tôi muốn chèn một tập hợp các giá trị n được biểu diễn dưới dạng vec-tơ vào một tập hợp các vị trí tương ứng trong một ma trận. Ứng dụng thực tế liên quan đến việc chèn một tập hợp các giá trị nhiệt độ bề mặt biển vào một hình ảnh của một vùng được biểu diễn dưới dạng lưới với kích thước nrow x ncol> n trong đó tôi đã xác định được n pixel nước sẽ nhận được các giá trị nhiệt độ . Vấn đề tôi đã gặp phải là các giá trị nhiệt độ được sắp xếp như thể chúng là từ một ma trận cột lớn hơn là thứ tự hàng lớn được sử dụng để lập chỉ mục lưới R.Làm cách nào để chèn các giá trị từ một véc-tơ vào ma trận bằng cách sử dụng thứ tự cột lớn?

Đây là ví dụ về đồ chơi theo ý tôi.

> 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 

Kết quả mong muốn sẽ thay:

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

Tôi cho rằng tôi có thể chơi với transposing lưới điện, làm thay và sau đó transposing nó trở lại, nhưng tôi nghĩ rằng sẽ có một tốt hơn cách tiếp cận vấn đề này.

Trả lời

6

Dưới đây là một vài lựa chọn, mỗi trong số đó hoạt động trên các ma trận có kích thước tùy ý:


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

Tôi khá chắc chắn lựa chọn thứ hai của bạn chỉ hoạt động cho ma trận vuông (vì nó giống như tôi xuống dưới đây:)) ... Ví dụ cho một ma trận 4 bởi 5, 2 nên đi đến 6, nhưng với hàm trên, ' f (2, c (4,5)) == 5'. – jed

+0

@jed - Không, không đúng. Với ma trận 4x5, 2 * nên * ánh xạ tới 5. (Nó đếm ngược thông qua bốn phần tử trong cột đầu tiên, và sau đó quay trở lại ở đầu cột thứ hai khi nó đạt đến phần tử thứ năm). Hãy thử nó ra chính mình để thấy rằng điều này là chính xác, với 'lưới <- ma trận (0, nr = 4, nc = 5); lưới [f (2, mờ (lưới))] <- 99; lưới'. Ngoài ra, xin lỗi tôi đã không nhìn thấy và chỉ cần chỉnh sửa câu trả lời của bạn khi tôi trở lại đây để thêm của riêng tôi khá tương tự 'f' - Tôi đã +1 của bạn khi tôi nhận thấy nó một vài giờ trước! –

+0

Ah đúng, tôi đã đi sai đường. Như trong 6 nên đi đến 2, mà không xảy ra trong chức năng của bạn! – jed

3

Một cách để thực hiện việc này là tạo ma trận mới với dữ liệu bắt buộc, chỉ định byrow=TRUE khi được tạo. Để làm điều này, bạn phải tạo một vector trung gian để lưu trữ và chỉnh sửa dữ liệu của 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

Chỉ cần tò mò, tại sao 'as.numeric (lưới) '? 'grid' đã là số. Bạn có thể sử dụng 'c (lưới)' để thu gọn ma trận –

+0

Cuộc gọi tốt đẹp, cảm ơn bạn. – nrussell

3

Nếu bạn có một ma trận vuông, bạn có thể viết một hàm modulo nhỏ mà thay thế số của bạn với những người đúng:

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 

Bạn có thể làm điều này với một ma trận không vuông quá, nó chỉ là một chút khó khăn hơn.

3

Bạn có thể thực hiện một số thao tác với các chỉ mục. Đầu tiên, chúng ta tạo chuỗi theo chiều dài của ma trận theo số cột. Sau đó, chúng tôi lặp lại thêm 1 vào chuỗi. Chúng tôi làm điều đó cho số hàng. Sau đó, việc đặt vector đó cho vector vị trí sẽ cho chúng ta vị trí trong ma trận.

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 
Các vấn đề liên quan