Is there an R function to get the “weighted” sum of neighboring values of a matrix (for varying radius)?Transforming a table of Nearest Neighbor Distances into a Matrixk-neighbors of a given matrix M x NGet neighbors of specified matrix elementFor each element in a matrix, find the sum of all of its neighborsadjacency matrix find if neighboresCreating a weighted adjacency matrix with iterationsPrecomputed matrix for fitting with scikit neighbors/radius classificationFinding the sum of degree value of a node's neighborsGetting a weighted matrix from networkConvert a DataFrame into Adjacency/Weights Matrix in R

US Passport stamped in UK for 6 months twice

Are there any well known academic philosophy forums?

How to Pin Point Large File eating space in Fedora 18

What does this symbol on the box of power supply mean?

Why colon to denote that a value belongs to a type?

Image processing: Removal of two spots in fundus images

Should breaking down something like a door be adjudicated as an attempt to beat its AC and HP, or as an ability check against a set DC?

Is the Indo-European language family made up?

In general, would I need to season a meat when making a sauce?

Is it true that cut time means "play twice as fast as written"?

How can I tell if I'm being too picky as a referee?

Who will lead the country until there is a new Tory leader?

Python program to find the most frequent letter in a text

What to do when you've set the wrong ISO for your film?

Installed Electric Tankless Water Heater - Internet loss when active

Where is the logic in castrating fighters?

Is it rude to call a professor by their last name with no prefix in a non-academic setting?

In the current era, do any wizards survive from 1372 DR?

If a person had control of every single cell of their body, would they be able to transform into another creature?

Is it possible to play as a necromancer skeleton?

What does the view outside my ship traveling at light speed look like?

the meaning of 'carry' in a novel

Simple function that simulates survey results based on sample size and probability

When and what was the first 3D acceleration device ever released?



Is there an R function to get the “weighted” sum of neighboring values of a matrix (for varying radius)?


Transforming a table of Nearest Neighbor Distances into a Matrixk-neighbors of a given matrix M x NGet neighbors of specified matrix elementFor each element in a matrix, find the sum of all of its neighborsadjacency matrix find if neighboresCreating a weighted adjacency matrix with iterationsPrecomputed matrix for fitting with scikit neighbors/radius classificationFinding the sum of degree value of a node's neighborsGetting a weighted matrix from networkConvert a DataFrame into Adjacency/Weights Matrix in R






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








0















I have a matrix M (say r rows and c columns) and I would like to get the "weighted" sum for each matrix element based on it's neighbors and create a new matrix M2. The word neighbor could be within a radius of 1 (which is often called the Moore neighborhood in Cellular Automata theory) or the radius could be a different than 1, say, 2, 3, etc.



For a particular cell in the matrix M, say somewhere in the middle. Let's say position (i,j); then the (i,j)th cell has "eight" neighbors given by,



(i-1, j-1), (i-1, j), (i-1, j+1), (i, j-1), (i, j+1), (i+1, j-1), (i+1, j), (i+1, j+1).



I want to create a matrix M2 that calculates the "weighted" sum of the (i,j)th cell plus its eight neighbors. The weighting is done based on the Euclidean distance between cells. So for example,



exp(-sqrt(2))*M[i-1,j-1] + exp(-1)*M[i-1,j] + exp(-sqrt(2))*M[i-1,j+1] + exp(-1)*M[i,j-1] + M[i,j] + exp(-1)*M[i,j+1] + exp(-sqrt(2))*M[i+1,j-1] + exp(-1)*M[i+1,j] + exp(-sqrt(2))*M[i+1,j+1]


The same idea is repeated for all cells (cells along the boundaries need to be treated specially since they don't necessarily have eight neighboring cells). The above idea is for radius 1 but the code I am trying to develop needs to be generic for any radius.



r <- 4
c <- 4

n <- r*c

(M <- matrix(1:n, r, c))

addresses <- expand.grid(x = 1:r, y = 1:c)

#Got this code in the same forum

z <- rbind(c(-1,0,1,-1,1,-1,0,1),c(-1,-1,-1,0,0,1,1,1))

get.neighbors <- function(rw)
# Convert to absolute addresses
z2 <- t(z + unlist(rw))
# Choose those with indices within mat
b.good <- rowSums(z2 > 0)==2 & z2[,1] <= nrow(M) & z2[,2] <= ncol(M)
M[z2[b.good,]]


apply(addresses,1 , get.neighbors) # Returns a list with neighbors

M


Essentially, M2 for radius = 1 must be the "weighted" sum of the current cell plus the neighbors. The current current cell always gets a weight of 1.



M = [ 1 5 9 13
2 6 10 14
3 7 11 15
4 8 12 16]

M2 = [ 5.033 13.803 .... ....
.... .... .... ....
.... .... .... ....
.... .... .... ....]


How do I go about getting matrix M2 in R? What about if radius for more than 1? I would like the weighting to happening inside two for loops so I can use the calculated weighted sum of the [i,j] cell further in the code closing the two for loops.










share|improve this question
























  • Please don't ever include rm(list=ls()) in code posted in a question. It's akin to suggesting somebody run your code and it includes the old format C: DOS command.

    – r2evans
    Mar 24 at 5:50







  • 1





    Thank you r2evans. I ll remember to never include rm(list=ls()) in the future.

    – Ashok Krishnamurthy
    Mar 24 at 7:27

















0















I have a matrix M (say r rows and c columns) and I would like to get the "weighted" sum for each matrix element based on it's neighbors and create a new matrix M2. The word neighbor could be within a radius of 1 (which is often called the Moore neighborhood in Cellular Automata theory) or the radius could be a different than 1, say, 2, 3, etc.



For a particular cell in the matrix M, say somewhere in the middle. Let's say position (i,j); then the (i,j)th cell has "eight" neighbors given by,



(i-1, j-1), (i-1, j), (i-1, j+1), (i, j-1), (i, j+1), (i+1, j-1), (i+1, j), (i+1, j+1).



I want to create a matrix M2 that calculates the "weighted" sum of the (i,j)th cell plus its eight neighbors. The weighting is done based on the Euclidean distance between cells. So for example,



exp(-sqrt(2))*M[i-1,j-1] + exp(-1)*M[i-1,j] + exp(-sqrt(2))*M[i-1,j+1] + exp(-1)*M[i,j-1] + M[i,j] + exp(-1)*M[i,j+1] + exp(-sqrt(2))*M[i+1,j-1] + exp(-1)*M[i+1,j] + exp(-sqrt(2))*M[i+1,j+1]


The same idea is repeated for all cells (cells along the boundaries need to be treated specially since they don't necessarily have eight neighboring cells). The above idea is for radius 1 but the code I am trying to develop needs to be generic for any radius.



r <- 4
c <- 4

n <- r*c

(M <- matrix(1:n, r, c))

addresses <- expand.grid(x = 1:r, y = 1:c)

#Got this code in the same forum

z <- rbind(c(-1,0,1,-1,1,-1,0,1),c(-1,-1,-1,0,0,1,1,1))

get.neighbors <- function(rw)
# Convert to absolute addresses
z2 <- t(z + unlist(rw))
# Choose those with indices within mat
b.good <- rowSums(z2 > 0)==2 & z2[,1] <= nrow(M) & z2[,2] <= ncol(M)
M[z2[b.good,]]


apply(addresses,1 , get.neighbors) # Returns a list with neighbors

M


Essentially, M2 for radius = 1 must be the "weighted" sum of the current cell plus the neighbors. The current current cell always gets a weight of 1.



M = [ 1 5 9 13
2 6 10 14
3 7 11 15
4 8 12 16]

M2 = [ 5.033 13.803 .... ....
.... .... .... ....
.... .... .... ....
.... .... .... ....]


How do I go about getting matrix M2 in R? What about if radius for more than 1? I would like the weighting to happening inside two for loops so I can use the calculated weighted sum of the [i,j] cell further in the code closing the two for loops.










share|improve this question
























  • Please don't ever include rm(list=ls()) in code posted in a question. It's akin to suggesting somebody run your code and it includes the old format C: DOS command.

    – r2evans
    Mar 24 at 5:50







  • 1





    Thank you r2evans. I ll remember to never include rm(list=ls()) in the future.

    – Ashok Krishnamurthy
    Mar 24 at 7:27













0












0








0








I have a matrix M (say r rows and c columns) and I would like to get the "weighted" sum for each matrix element based on it's neighbors and create a new matrix M2. The word neighbor could be within a radius of 1 (which is often called the Moore neighborhood in Cellular Automata theory) or the radius could be a different than 1, say, 2, 3, etc.



For a particular cell in the matrix M, say somewhere in the middle. Let's say position (i,j); then the (i,j)th cell has "eight" neighbors given by,



(i-1, j-1), (i-1, j), (i-1, j+1), (i, j-1), (i, j+1), (i+1, j-1), (i+1, j), (i+1, j+1).



I want to create a matrix M2 that calculates the "weighted" sum of the (i,j)th cell plus its eight neighbors. The weighting is done based on the Euclidean distance between cells. So for example,



exp(-sqrt(2))*M[i-1,j-1] + exp(-1)*M[i-1,j] + exp(-sqrt(2))*M[i-1,j+1] + exp(-1)*M[i,j-1] + M[i,j] + exp(-1)*M[i,j+1] + exp(-sqrt(2))*M[i+1,j-1] + exp(-1)*M[i+1,j] + exp(-sqrt(2))*M[i+1,j+1]


The same idea is repeated for all cells (cells along the boundaries need to be treated specially since they don't necessarily have eight neighboring cells). The above idea is for radius 1 but the code I am trying to develop needs to be generic for any radius.



r <- 4
c <- 4

n <- r*c

(M <- matrix(1:n, r, c))

addresses <- expand.grid(x = 1:r, y = 1:c)

#Got this code in the same forum

z <- rbind(c(-1,0,1,-1,1,-1,0,1),c(-1,-1,-1,0,0,1,1,1))

get.neighbors <- function(rw)
# Convert to absolute addresses
z2 <- t(z + unlist(rw))
# Choose those with indices within mat
b.good <- rowSums(z2 > 0)==2 & z2[,1] <= nrow(M) & z2[,2] <= ncol(M)
M[z2[b.good,]]


apply(addresses,1 , get.neighbors) # Returns a list with neighbors

M


Essentially, M2 for radius = 1 must be the "weighted" sum of the current cell plus the neighbors. The current current cell always gets a weight of 1.



M = [ 1 5 9 13
2 6 10 14
3 7 11 15
4 8 12 16]

M2 = [ 5.033 13.803 .... ....
.... .... .... ....
.... .... .... ....
.... .... .... ....]


How do I go about getting matrix M2 in R? What about if radius for more than 1? I would like the weighting to happening inside two for loops so I can use the calculated weighted sum of the [i,j] cell further in the code closing the two for loops.










share|improve this question
















I have a matrix M (say r rows and c columns) and I would like to get the "weighted" sum for each matrix element based on it's neighbors and create a new matrix M2. The word neighbor could be within a radius of 1 (which is often called the Moore neighborhood in Cellular Automata theory) or the radius could be a different than 1, say, 2, 3, etc.



For a particular cell in the matrix M, say somewhere in the middle. Let's say position (i,j); then the (i,j)th cell has "eight" neighbors given by,



(i-1, j-1), (i-1, j), (i-1, j+1), (i, j-1), (i, j+1), (i+1, j-1), (i+1, j), (i+1, j+1).



I want to create a matrix M2 that calculates the "weighted" sum of the (i,j)th cell plus its eight neighbors. The weighting is done based on the Euclidean distance between cells. So for example,



exp(-sqrt(2))*M[i-1,j-1] + exp(-1)*M[i-1,j] + exp(-sqrt(2))*M[i-1,j+1] + exp(-1)*M[i,j-1] + M[i,j] + exp(-1)*M[i,j+1] + exp(-sqrt(2))*M[i+1,j-1] + exp(-1)*M[i+1,j] + exp(-sqrt(2))*M[i+1,j+1]


The same idea is repeated for all cells (cells along the boundaries need to be treated specially since they don't necessarily have eight neighboring cells). The above idea is for radius 1 but the code I am trying to develop needs to be generic for any radius.



r <- 4
c <- 4

n <- r*c

(M <- matrix(1:n, r, c))

addresses <- expand.grid(x = 1:r, y = 1:c)

#Got this code in the same forum

z <- rbind(c(-1,0,1,-1,1,-1,0,1),c(-1,-1,-1,0,0,1,1,1))

get.neighbors <- function(rw)
# Convert to absolute addresses
z2 <- t(z + unlist(rw))
# Choose those with indices within mat
b.good <- rowSums(z2 > 0)==2 & z2[,1] <= nrow(M) & z2[,2] <= ncol(M)
M[z2[b.good,]]


apply(addresses,1 , get.neighbors) # Returns a list with neighbors

M


Essentially, M2 for radius = 1 must be the "weighted" sum of the current cell plus the neighbors. The current current cell always gets a weight of 1.



M = [ 1 5 9 13
2 6 10 14
3 7 11 15
4 8 12 16]

M2 = [ 5.033 13.803 .... ....
.... .... .... ....
.... .... .... ....
.... .... .... ....]


How do I go about getting matrix M2 in R? What about if radius for more than 1? I would like the weighting to happening inside two for loops so I can use the calculated weighted sum of the [i,j] cell further in the code closing the two for loops.







r for-loop matrix nearest-neighbor adjacency-matrix






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 24 at 8:02







Ashok Krishnamurthy

















asked Mar 24 at 5:23









Ashok KrishnamurthyAshok Krishnamurthy

1717




1717












  • Please don't ever include rm(list=ls()) in code posted in a question. It's akin to suggesting somebody run your code and it includes the old format C: DOS command.

    – r2evans
    Mar 24 at 5:50







  • 1





    Thank you r2evans. I ll remember to never include rm(list=ls()) in the future.

    – Ashok Krishnamurthy
    Mar 24 at 7:27

















  • Please don't ever include rm(list=ls()) in code posted in a question. It's akin to suggesting somebody run your code and it includes the old format C: DOS command.

    – r2evans
    Mar 24 at 5:50







  • 1





    Thank you r2evans. I ll remember to never include rm(list=ls()) in the future.

    – Ashok Krishnamurthy
    Mar 24 at 7:27
















Please don't ever include rm(list=ls()) in code posted in a question. It's akin to suggesting somebody run your code and it includes the old format C: DOS command.

– r2evans
Mar 24 at 5:50






Please don't ever include rm(list=ls()) in code posted in a question. It's akin to suggesting somebody run your code and it includes the old format C: DOS command.

– r2evans
Mar 24 at 5:50





1




1





Thank you r2evans. I ll remember to never include rm(list=ls()) in the future.

– Ashok Krishnamurthy
Mar 24 at 7:27





Thank you r2evans. I ll remember to never include rm(list=ls()) in the future.

– Ashok Krishnamurthy
Mar 24 at 7:27












2 Answers
2






active

oldest

votes


















0














I think the following does the weighted sum that you want. I'll be finding the neighbours in a similar way @r2evans did.



wtd_nbrs_sum <- function(input_matrix,
radius,
weight_matrix)

temp_1 <- matrix(data = 0,
nrow = nrow(x = input_matrix),
ncol = radius)
temp_2 <- matrix(data = 0,
nrow = radius,
ncol = ((2 * radius) + ncol(x = input_matrix)))
input_matrix_modified <- rbind(temp_2,
cbind(temp_1, input_matrix, temp_1),
temp_2)
output_matrix <- matrix(nrow = nrow(x = input_matrix),
ncol = ncol(x = input_matrix))
for(i in seq_len(length.out = nrow(x = input_matrix)))

for(j in seq_len(length.out = nrow(x = input_matrix)))

row_min <- (radius + (i - radius))
row_max <- (radius + (i + radius))
column_min <- (radius + (j - radius))
column_max <- (radius + (j + radius))
neighbours <- input_matrix_modified[(row_min:row_max), (column_min:column_max)]
weighted_sum <- sum(neighbours * weight_matrix)
output_matrix[i, j] <- weighted_sum


return(output_matrix)


r <- 4
c <- 4
n <- r*c
M <- matrix(data = 1:n,
nrow = r,
ncol = c)
R <- 1
wts <- matrix(data = c(exp(x = -sqrt(x = 2)), exp(x = -1), exp(x = -sqrt(x = 2)), exp(x = -1), 1, exp(x = -1), exp(x = -sqrt(x = 2)), exp(x = -1), exp(x = -sqrt(x = 2))),
nrow = 3,
ncol = 3)

wtd_nbrs_sum(input_matrix = M,
radius = R,
weight_matrix = wts)
#> [,1] [,2] [,3] [,4]
#> [1,] 5.033856 13.80347 24.16296 23.89239
#> [2,] 8.596195 20.66391 34.43985 32.84175
#> [3,] 11.186067 24.10789 37.88383 35.43163
#> [4,] 9.748491 19.86486 30.22435 28.60703


Created on 2019-03-24 by the reprex package (v0.2.1)



Hope this helps.






share|improve this answer























  • Thank you @yarnabrina I am getting an error Error in neighbours * weight_matrix : non-conformable arrays when I change R = 2. I see the wts matrix is 3 x 3 for R = 1 but as R increases wts also increases in the weighted distance calculation. Any help is highly appreciated.

    – Ashok Krishnamurthy
    Mar 24 at 18:21











  • @AshokKrishnamurthy If radius is R, then you'll be need to update the weight matrix to a (2R+1)x(2R+1) matrix. So, if you try R=2, get a 5x5 matrix wts and then run wtd_nbrs_sum(input_matrix = M, radius = R, weight_matrix = wts).

    – yarnabrina
    Mar 25 at 1:24



















0














Edited to include weighted-sums.



There might be a really neat trick to doing it, but the most straight-forward (and maintainable) way is probably a simple two-for-loop implementation.



M1 <- matrix(1:16, nr=4)
M1
# [,1] [,2] [,3] [,4]
# [1,] 1 5 9 13
# [2,] 2 6 10 14
# [3,] 3 7 11 15
# [4,] 4 8 12 16


The code:



get_neighbors <- function(M, radius = 1) 
M2 <- M
M2[] <- 0
nr <- nrow(M)
nc <- ncol(M)
eg <- expand.grid((-radius):radius, (-radius):radius)
eg$wt <- exp(-sqrt(abs(eg[,1]) + abs(eg[,2])))
for (R in seq_len(nr))
for (C in seq_len(nc))
ind <- cbind(R + eg[,1], C + eg[,2], eg[,3])
ind <- ind[ 0 < ind[,1] & ind[,1] <= nr &
0 < ind[,2] & ind[,2] <= nc,, drop = FALSE ]
M2[R,C] <- sum(M[ind[,1:2, drop=FALSE]] * ind[,3])


M2


get_neighbors(M1, 1)
# [,1] [,2] [,3] [,4]
# [1,] 5.033856 13.80347 24.16296 23.89239
# [2,] 8.596195 20.66391 34.43985 32.84175
# [3,] 11.186067 24.10789 37.88383 35.43163
# [4,] 9.748491 19.86486 30.22435 28.60703


The same thing, with radius 2:



get_neighbors(M1, 2)
# [,1] [,2] [,3] [,4]
# [1,] 12.44761 25.64963 31.73247 32.70974
# [2,] 18.57765 35.96237 43.33862 43.51911
# [3,] 20.09836 37.80643 45.18268 45.03982
# [4,] 17.51314 31.88500 37.96784 37.77527


And a simple test, if radius 0 is used, then M1 and M2 should be identical (they are).



Note: this generally performs just fine in base R, with no fancy use of apply or its cousins. Since this is a really straight-forward heuristic, it could easily be implemented with Rcpp to be significantly faster.






share|improve this answer

























  • @AshokKrishnamurthy, see the edit.

    – r2evans
    Mar 24 at 19:24











Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55320963%2fis-there-an-r-function-to-get-the-weighted-sum-of-neighboring-values-of-a-matr%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









0














I think the following does the weighted sum that you want. I'll be finding the neighbours in a similar way @r2evans did.



wtd_nbrs_sum <- function(input_matrix,
radius,
weight_matrix)

temp_1 <- matrix(data = 0,
nrow = nrow(x = input_matrix),
ncol = radius)
temp_2 <- matrix(data = 0,
nrow = radius,
ncol = ((2 * radius) + ncol(x = input_matrix)))
input_matrix_modified <- rbind(temp_2,
cbind(temp_1, input_matrix, temp_1),
temp_2)
output_matrix <- matrix(nrow = nrow(x = input_matrix),
ncol = ncol(x = input_matrix))
for(i in seq_len(length.out = nrow(x = input_matrix)))

for(j in seq_len(length.out = nrow(x = input_matrix)))

row_min <- (radius + (i - radius))
row_max <- (radius + (i + radius))
column_min <- (radius + (j - radius))
column_max <- (radius + (j + radius))
neighbours <- input_matrix_modified[(row_min:row_max), (column_min:column_max)]
weighted_sum <- sum(neighbours * weight_matrix)
output_matrix[i, j] <- weighted_sum


return(output_matrix)


r <- 4
c <- 4
n <- r*c
M <- matrix(data = 1:n,
nrow = r,
ncol = c)
R <- 1
wts <- matrix(data = c(exp(x = -sqrt(x = 2)), exp(x = -1), exp(x = -sqrt(x = 2)), exp(x = -1), 1, exp(x = -1), exp(x = -sqrt(x = 2)), exp(x = -1), exp(x = -sqrt(x = 2))),
nrow = 3,
ncol = 3)

wtd_nbrs_sum(input_matrix = M,
radius = R,
weight_matrix = wts)
#> [,1] [,2] [,3] [,4]
#> [1,] 5.033856 13.80347 24.16296 23.89239
#> [2,] 8.596195 20.66391 34.43985 32.84175
#> [3,] 11.186067 24.10789 37.88383 35.43163
#> [4,] 9.748491 19.86486 30.22435 28.60703


Created on 2019-03-24 by the reprex package (v0.2.1)



Hope this helps.






share|improve this answer























  • Thank you @yarnabrina I am getting an error Error in neighbours * weight_matrix : non-conformable arrays when I change R = 2. I see the wts matrix is 3 x 3 for R = 1 but as R increases wts also increases in the weighted distance calculation. Any help is highly appreciated.

    – Ashok Krishnamurthy
    Mar 24 at 18:21











  • @AshokKrishnamurthy If radius is R, then you'll be need to update the weight matrix to a (2R+1)x(2R+1) matrix. So, if you try R=2, get a 5x5 matrix wts and then run wtd_nbrs_sum(input_matrix = M, radius = R, weight_matrix = wts).

    – yarnabrina
    Mar 25 at 1:24
















0














I think the following does the weighted sum that you want. I'll be finding the neighbours in a similar way @r2evans did.



wtd_nbrs_sum <- function(input_matrix,
radius,
weight_matrix)

temp_1 <- matrix(data = 0,
nrow = nrow(x = input_matrix),
ncol = radius)
temp_2 <- matrix(data = 0,
nrow = radius,
ncol = ((2 * radius) + ncol(x = input_matrix)))
input_matrix_modified <- rbind(temp_2,
cbind(temp_1, input_matrix, temp_1),
temp_2)
output_matrix <- matrix(nrow = nrow(x = input_matrix),
ncol = ncol(x = input_matrix))
for(i in seq_len(length.out = nrow(x = input_matrix)))

for(j in seq_len(length.out = nrow(x = input_matrix)))

row_min <- (radius + (i - radius))
row_max <- (radius + (i + radius))
column_min <- (radius + (j - radius))
column_max <- (radius + (j + radius))
neighbours <- input_matrix_modified[(row_min:row_max), (column_min:column_max)]
weighted_sum <- sum(neighbours * weight_matrix)
output_matrix[i, j] <- weighted_sum


return(output_matrix)


r <- 4
c <- 4
n <- r*c
M <- matrix(data = 1:n,
nrow = r,
ncol = c)
R <- 1
wts <- matrix(data = c(exp(x = -sqrt(x = 2)), exp(x = -1), exp(x = -sqrt(x = 2)), exp(x = -1), 1, exp(x = -1), exp(x = -sqrt(x = 2)), exp(x = -1), exp(x = -sqrt(x = 2))),
nrow = 3,
ncol = 3)

wtd_nbrs_sum(input_matrix = M,
radius = R,
weight_matrix = wts)
#> [,1] [,2] [,3] [,4]
#> [1,] 5.033856 13.80347 24.16296 23.89239
#> [2,] 8.596195 20.66391 34.43985 32.84175
#> [3,] 11.186067 24.10789 37.88383 35.43163
#> [4,] 9.748491 19.86486 30.22435 28.60703


Created on 2019-03-24 by the reprex package (v0.2.1)



Hope this helps.






share|improve this answer























  • Thank you @yarnabrina I am getting an error Error in neighbours * weight_matrix : non-conformable arrays when I change R = 2. I see the wts matrix is 3 x 3 for R = 1 but as R increases wts also increases in the weighted distance calculation. Any help is highly appreciated.

    – Ashok Krishnamurthy
    Mar 24 at 18:21











  • @AshokKrishnamurthy If radius is R, then you'll be need to update the weight matrix to a (2R+1)x(2R+1) matrix. So, if you try R=2, get a 5x5 matrix wts and then run wtd_nbrs_sum(input_matrix = M, radius = R, weight_matrix = wts).

    – yarnabrina
    Mar 25 at 1:24














0












0








0







I think the following does the weighted sum that you want. I'll be finding the neighbours in a similar way @r2evans did.



wtd_nbrs_sum <- function(input_matrix,
radius,
weight_matrix)

temp_1 <- matrix(data = 0,
nrow = nrow(x = input_matrix),
ncol = radius)
temp_2 <- matrix(data = 0,
nrow = radius,
ncol = ((2 * radius) + ncol(x = input_matrix)))
input_matrix_modified <- rbind(temp_2,
cbind(temp_1, input_matrix, temp_1),
temp_2)
output_matrix <- matrix(nrow = nrow(x = input_matrix),
ncol = ncol(x = input_matrix))
for(i in seq_len(length.out = nrow(x = input_matrix)))

for(j in seq_len(length.out = nrow(x = input_matrix)))

row_min <- (radius + (i - radius))
row_max <- (radius + (i + radius))
column_min <- (radius + (j - radius))
column_max <- (radius + (j + radius))
neighbours <- input_matrix_modified[(row_min:row_max), (column_min:column_max)]
weighted_sum <- sum(neighbours * weight_matrix)
output_matrix[i, j] <- weighted_sum


return(output_matrix)


r <- 4
c <- 4
n <- r*c
M <- matrix(data = 1:n,
nrow = r,
ncol = c)
R <- 1
wts <- matrix(data = c(exp(x = -sqrt(x = 2)), exp(x = -1), exp(x = -sqrt(x = 2)), exp(x = -1), 1, exp(x = -1), exp(x = -sqrt(x = 2)), exp(x = -1), exp(x = -sqrt(x = 2))),
nrow = 3,
ncol = 3)

wtd_nbrs_sum(input_matrix = M,
radius = R,
weight_matrix = wts)
#> [,1] [,2] [,3] [,4]
#> [1,] 5.033856 13.80347 24.16296 23.89239
#> [2,] 8.596195 20.66391 34.43985 32.84175
#> [3,] 11.186067 24.10789 37.88383 35.43163
#> [4,] 9.748491 19.86486 30.22435 28.60703


Created on 2019-03-24 by the reprex package (v0.2.1)



Hope this helps.






share|improve this answer













I think the following does the weighted sum that you want. I'll be finding the neighbours in a similar way @r2evans did.



wtd_nbrs_sum <- function(input_matrix,
radius,
weight_matrix)

temp_1 <- matrix(data = 0,
nrow = nrow(x = input_matrix),
ncol = radius)
temp_2 <- matrix(data = 0,
nrow = radius,
ncol = ((2 * radius) + ncol(x = input_matrix)))
input_matrix_modified <- rbind(temp_2,
cbind(temp_1, input_matrix, temp_1),
temp_2)
output_matrix <- matrix(nrow = nrow(x = input_matrix),
ncol = ncol(x = input_matrix))
for(i in seq_len(length.out = nrow(x = input_matrix)))

for(j in seq_len(length.out = nrow(x = input_matrix)))

row_min <- (radius + (i - radius))
row_max <- (radius + (i + radius))
column_min <- (radius + (j - radius))
column_max <- (radius + (j + radius))
neighbours <- input_matrix_modified[(row_min:row_max), (column_min:column_max)]
weighted_sum <- sum(neighbours * weight_matrix)
output_matrix[i, j] <- weighted_sum


return(output_matrix)


r <- 4
c <- 4
n <- r*c
M <- matrix(data = 1:n,
nrow = r,
ncol = c)
R <- 1
wts <- matrix(data = c(exp(x = -sqrt(x = 2)), exp(x = -1), exp(x = -sqrt(x = 2)), exp(x = -1), 1, exp(x = -1), exp(x = -sqrt(x = 2)), exp(x = -1), exp(x = -sqrt(x = 2))),
nrow = 3,
ncol = 3)

wtd_nbrs_sum(input_matrix = M,
radius = R,
weight_matrix = wts)
#> [,1] [,2] [,3] [,4]
#> [1,] 5.033856 13.80347 24.16296 23.89239
#> [2,] 8.596195 20.66391 34.43985 32.84175
#> [3,] 11.186067 24.10789 37.88383 35.43163
#> [4,] 9.748491 19.86486 30.22435 28.60703


Created on 2019-03-24 by the reprex package (v0.2.1)



Hope this helps.







share|improve this answer












share|improve this answer



share|improve this answer










answered Mar 24 at 15:48









yarnabrinayarnabrina

640111




640111












  • Thank you @yarnabrina I am getting an error Error in neighbours * weight_matrix : non-conformable arrays when I change R = 2. I see the wts matrix is 3 x 3 for R = 1 but as R increases wts also increases in the weighted distance calculation. Any help is highly appreciated.

    – Ashok Krishnamurthy
    Mar 24 at 18:21











  • @AshokKrishnamurthy If radius is R, then you'll be need to update the weight matrix to a (2R+1)x(2R+1) matrix. So, if you try R=2, get a 5x5 matrix wts and then run wtd_nbrs_sum(input_matrix = M, radius = R, weight_matrix = wts).

    – yarnabrina
    Mar 25 at 1:24


















  • Thank you @yarnabrina I am getting an error Error in neighbours * weight_matrix : non-conformable arrays when I change R = 2. I see the wts matrix is 3 x 3 for R = 1 but as R increases wts also increases in the weighted distance calculation. Any help is highly appreciated.

    – Ashok Krishnamurthy
    Mar 24 at 18:21











  • @AshokKrishnamurthy If radius is R, then you'll be need to update the weight matrix to a (2R+1)x(2R+1) matrix. So, if you try R=2, get a 5x5 matrix wts and then run wtd_nbrs_sum(input_matrix = M, radius = R, weight_matrix = wts).

    – yarnabrina
    Mar 25 at 1:24

















Thank you @yarnabrina I am getting an error Error in neighbours * weight_matrix : non-conformable arrays when I change R = 2. I see the wts matrix is 3 x 3 for R = 1 but as R increases wts also increases in the weighted distance calculation. Any help is highly appreciated.

– Ashok Krishnamurthy
Mar 24 at 18:21





Thank you @yarnabrina I am getting an error Error in neighbours * weight_matrix : non-conformable arrays when I change R = 2. I see the wts matrix is 3 x 3 for R = 1 but as R increases wts also increases in the weighted distance calculation. Any help is highly appreciated.

– Ashok Krishnamurthy
Mar 24 at 18:21













@AshokKrishnamurthy If radius is R, then you'll be need to update the weight matrix to a (2R+1)x(2R+1) matrix. So, if you try R=2, get a 5x5 matrix wts and then run wtd_nbrs_sum(input_matrix = M, radius = R, weight_matrix = wts).

– yarnabrina
Mar 25 at 1:24






@AshokKrishnamurthy If radius is R, then you'll be need to update the weight matrix to a (2R+1)x(2R+1) matrix. So, if you try R=2, get a 5x5 matrix wts and then run wtd_nbrs_sum(input_matrix = M, radius = R, weight_matrix = wts).

– yarnabrina
Mar 25 at 1:24














0














Edited to include weighted-sums.



There might be a really neat trick to doing it, but the most straight-forward (and maintainable) way is probably a simple two-for-loop implementation.



M1 <- matrix(1:16, nr=4)
M1
# [,1] [,2] [,3] [,4]
# [1,] 1 5 9 13
# [2,] 2 6 10 14
# [3,] 3 7 11 15
# [4,] 4 8 12 16


The code:



get_neighbors <- function(M, radius = 1) 
M2 <- M
M2[] <- 0
nr <- nrow(M)
nc <- ncol(M)
eg <- expand.grid((-radius):radius, (-radius):radius)
eg$wt <- exp(-sqrt(abs(eg[,1]) + abs(eg[,2])))
for (R in seq_len(nr))
for (C in seq_len(nc))
ind <- cbind(R + eg[,1], C + eg[,2], eg[,3])
ind <- ind[ 0 < ind[,1] & ind[,1] <= nr &
0 < ind[,2] & ind[,2] <= nc,, drop = FALSE ]
M2[R,C] <- sum(M[ind[,1:2, drop=FALSE]] * ind[,3])


M2


get_neighbors(M1, 1)
# [,1] [,2] [,3] [,4]
# [1,] 5.033856 13.80347 24.16296 23.89239
# [2,] 8.596195 20.66391 34.43985 32.84175
# [3,] 11.186067 24.10789 37.88383 35.43163
# [4,] 9.748491 19.86486 30.22435 28.60703


The same thing, with radius 2:



get_neighbors(M1, 2)
# [,1] [,2] [,3] [,4]
# [1,] 12.44761 25.64963 31.73247 32.70974
# [2,] 18.57765 35.96237 43.33862 43.51911
# [3,] 20.09836 37.80643 45.18268 45.03982
# [4,] 17.51314 31.88500 37.96784 37.77527


And a simple test, if radius 0 is used, then M1 and M2 should be identical (they are).



Note: this generally performs just fine in base R, with no fancy use of apply or its cousins. Since this is a really straight-forward heuristic, it could easily be implemented with Rcpp to be significantly faster.






share|improve this answer

























  • @AshokKrishnamurthy, see the edit.

    – r2evans
    Mar 24 at 19:24















0














Edited to include weighted-sums.



There might be a really neat trick to doing it, but the most straight-forward (and maintainable) way is probably a simple two-for-loop implementation.



M1 <- matrix(1:16, nr=4)
M1
# [,1] [,2] [,3] [,4]
# [1,] 1 5 9 13
# [2,] 2 6 10 14
# [3,] 3 7 11 15
# [4,] 4 8 12 16


The code:



get_neighbors <- function(M, radius = 1) 
M2 <- M
M2[] <- 0
nr <- nrow(M)
nc <- ncol(M)
eg <- expand.grid((-radius):radius, (-radius):radius)
eg$wt <- exp(-sqrt(abs(eg[,1]) + abs(eg[,2])))
for (R in seq_len(nr))
for (C in seq_len(nc))
ind <- cbind(R + eg[,1], C + eg[,2], eg[,3])
ind <- ind[ 0 < ind[,1] & ind[,1] <= nr &
0 < ind[,2] & ind[,2] <= nc,, drop = FALSE ]
M2[R,C] <- sum(M[ind[,1:2, drop=FALSE]] * ind[,3])


M2


get_neighbors(M1, 1)
# [,1] [,2] [,3] [,4]
# [1,] 5.033856 13.80347 24.16296 23.89239
# [2,] 8.596195 20.66391 34.43985 32.84175
# [3,] 11.186067 24.10789 37.88383 35.43163
# [4,] 9.748491 19.86486 30.22435 28.60703


The same thing, with radius 2:



get_neighbors(M1, 2)
# [,1] [,2] [,3] [,4]
# [1,] 12.44761 25.64963 31.73247 32.70974
# [2,] 18.57765 35.96237 43.33862 43.51911
# [3,] 20.09836 37.80643 45.18268 45.03982
# [4,] 17.51314 31.88500 37.96784 37.77527


And a simple test, if radius 0 is used, then M1 and M2 should be identical (they are).



Note: this generally performs just fine in base R, with no fancy use of apply or its cousins. Since this is a really straight-forward heuristic, it could easily be implemented with Rcpp to be significantly faster.






share|improve this answer

























  • @AshokKrishnamurthy, see the edit.

    – r2evans
    Mar 24 at 19:24













0












0








0







Edited to include weighted-sums.



There might be a really neat trick to doing it, but the most straight-forward (and maintainable) way is probably a simple two-for-loop implementation.



M1 <- matrix(1:16, nr=4)
M1
# [,1] [,2] [,3] [,4]
# [1,] 1 5 9 13
# [2,] 2 6 10 14
# [3,] 3 7 11 15
# [4,] 4 8 12 16


The code:



get_neighbors <- function(M, radius = 1) 
M2 <- M
M2[] <- 0
nr <- nrow(M)
nc <- ncol(M)
eg <- expand.grid((-radius):radius, (-radius):radius)
eg$wt <- exp(-sqrt(abs(eg[,1]) + abs(eg[,2])))
for (R in seq_len(nr))
for (C in seq_len(nc))
ind <- cbind(R + eg[,1], C + eg[,2], eg[,3])
ind <- ind[ 0 < ind[,1] & ind[,1] <= nr &
0 < ind[,2] & ind[,2] <= nc,, drop = FALSE ]
M2[R,C] <- sum(M[ind[,1:2, drop=FALSE]] * ind[,3])


M2


get_neighbors(M1, 1)
# [,1] [,2] [,3] [,4]
# [1,] 5.033856 13.80347 24.16296 23.89239
# [2,] 8.596195 20.66391 34.43985 32.84175
# [3,] 11.186067 24.10789 37.88383 35.43163
# [4,] 9.748491 19.86486 30.22435 28.60703


The same thing, with radius 2:



get_neighbors(M1, 2)
# [,1] [,2] [,3] [,4]
# [1,] 12.44761 25.64963 31.73247 32.70974
# [2,] 18.57765 35.96237 43.33862 43.51911
# [3,] 20.09836 37.80643 45.18268 45.03982
# [4,] 17.51314 31.88500 37.96784 37.77527


And a simple test, if radius 0 is used, then M1 and M2 should be identical (they are).



Note: this generally performs just fine in base R, with no fancy use of apply or its cousins. Since this is a really straight-forward heuristic, it could easily be implemented with Rcpp to be significantly faster.






share|improve this answer















Edited to include weighted-sums.



There might be a really neat trick to doing it, but the most straight-forward (and maintainable) way is probably a simple two-for-loop implementation.



M1 <- matrix(1:16, nr=4)
M1
# [,1] [,2] [,3] [,4]
# [1,] 1 5 9 13
# [2,] 2 6 10 14
# [3,] 3 7 11 15
# [4,] 4 8 12 16


The code:



get_neighbors <- function(M, radius = 1) 
M2 <- M
M2[] <- 0
nr <- nrow(M)
nc <- ncol(M)
eg <- expand.grid((-radius):radius, (-radius):radius)
eg$wt <- exp(-sqrt(abs(eg[,1]) + abs(eg[,2])))
for (R in seq_len(nr))
for (C in seq_len(nc))
ind <- cbind(R + eg[,1], C + eg[,2], eg[,3])
ind <- ind[ 0 < ind[,1] & ind[,1] <= nr &
0 < ind[,2] & ind[,2] <= nc,, drop = FALSE ]
M2[R,C] <- sum(M[ind[,1:2, drop=FALSE]] * ind[,3])


M2


get_neighbors(M1, 1)
# [,1] [,2] [,3] [,4]
# [1,] 5.033856 13.80347 24.16296 23.89239
# [2,] 8.596195 20.66391 34.43985 32.84175
# [3,] 11.186067 24.10789 37.88383 35.43163
# [4,] 9.748491 19.86486 30.22435 28.60703


The same thing, with radius 2:



get_neighbors(M1, 2)
# [,1] [,2] [,3] [,4]
# [1,] 12.44761 25.64963 31.73247 32.70974
# [2,] 18.57765 35.96237 43.33862 43.51911
# [3,] 20.09836 37.80643 45.18268 45.03982
# [4,] 17.51314 31.88500 37.96784 37.77527


And a simple test, if radius 0 is used, then M1 and M2 should be identical (they are).



Note: this generally performs just fine in base R, with no fancy use of apply or its cousins. Since this is a really straight-forward heuristic, it could easily be implemented with Rcpp to be significantly faster.







share|improve this answer














share|improve this answer



share|improve this answer








edited Mar 24 at 19:23

























answered Mar 24 at 5:58









r2evansr2evans

29.4k33259




29.4k33259












  • @AshokKrishnamurthy, see the edit.

    – r2evans
    Mar 24 at 19:24

















  • @AshokKrishnamurthy, see the edit.

    – r2evans
    Mar 24 at 19:24
















@AshokKrishnamurthy, see the edit.

– r2evans
Mar 24 at 19:24





@AshokKrishnamurthy, see the edit.

– r2evans
Mar 24 at 19:24

















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55320963%2fis-there-an-r-function-to-get-the-weighted-sum-of-neighboring-values-of-a-matr%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

Swift 4 - func physicsWorld not invoked on collision? The Next CEO of Stack OverflowHow to call Objective-C code from Swift#ifdef replacement in the Swift language@selector() in Swift?#pragma mark in Swift?Swift for loop: for index, element in array?dispatch_after - GCD in Swift?Swift Beta performance: sorting arraysSplit a String into an array in Swift?The use of Swift 3 @objc inference in Swift 4 mode is deprecated?How to optimize UITableViewCell, because my UITableView lags

Access current req object everywhere in Node.js ExpressWhy are global variables considered bad practice? (node.js)Using req & res across functionsHow do I get the path to the current script with Node.js?What is Node.js' Connect, Express and “middleware”?Node.js w/ express error handling in callbackHow to access the GET parameters after “?” in Express?Modify Node.js req object parametersAccess “app” variable inside of ExpressJS/ConnectJS middleware?Node.js Express app - request objectAngular Http Module considered middleware?Session variables in ExpressJSAdd properties to the req object in expressjs with Typescript