how fill na in matrix with neighbor? R - r

this my first question and I hope to collaborate in the community.
I am in a project in which I must fill the NA values ​​with the average of their neighbors from a matrix of ncol = 10 and nrow = 10. I have developed the following code however it is very computationally inefficient:
Code
get_neighbor <- function(matrix, x=1,y=1){
z <- complex(real = rep(1:nrow(matrix), ncol(matrix)),
imaginary = rep(1:ncol(matrix), each = nrow(matrix)))
lookup <- lapply(seq_along(z), function(x){
# calcular la distantancia
dist <- which(abs(z - z[x]) < 2)
# sacar el elemento x del vecindario
dist[which(dist != x)]
})
index <- (y-1)*(nrow(matrix))+x
matrix[lookup[[index]]]
}
nn_mean <- function(a){
if(sum(is.na(a))!=ncol(a)*nrow(a)){
C <- permutations(2, 2, c(1,dim(a)[1]), repeats.allowed = T)
Borders <- data.frame(matrix(data = 0, ncol = 2, nrow = nrow(a)*2 + ncol(a)*2 - 4))
Borders[1:nrow(a), 1] <- 1:nrow(a); Borders[1:nrow(a), 2] <- 1
for(i in 2:(ncol(a)-1)){
Borders[i + nrow(a) - 1, 2] <- i; Borders[i + 2*(nrow(a) - 1) - 1, 2] <- i
Borders[i + nrow(a) - 1, 1] <- 1; Borders[i + 2*(nrow(a) - 1) - 1, 1] <- nrow(a)
}
Borders[1:ncol(a) + 3*(nrow(a))-4, 2] <- ncol(a)
Borders[1:ncol(a) + 3*(nrow(a))-4, 1] <- 1:ncol(a)
id <- which(is.na(a), arr.ind = T)
id <- data.frame(cbind(id, rep(0, nrow(id))))
while(nrow(id)!=0){
for(i in 1:nrow(id)){
id[i,3] <- sum(is.na(get_neighbor(a, id[i, 1], id[i, 2])))
}
max_na <- max(id[, 3])
for(i in 1:(nrow(a)*2 + ncol(a)*2 - 4)){
if(is.na(a[Borders[i, 1], Borders[i, 2]]) & sum(is.na(get_neighbor(a, Borders[i, 1], Borders[i, 2]))) == 5){
index <- which(id[,1] == Borders[i, 1] & id[,2] == Borders[i, 2])
id[index, 3] <- max_na +1
}
}
for(i in 1:4){
if(is.na(a[C[i,1], C[i,2]]) & sum(is.na(get_neighbor(a, C[i, 1], C[i, 2]))) == 3){
index <- which(id[,1] == C[i, 1] & id[,2] == C[i, 2])
id[index, 3] <- max_na +1
}
}
id <- id[order(id[,3]),]
index <- which(id[,3]== min(id[,3]))
for(i in 1:length(index)){
a[id[i, 1], id[i, 2]] <- mean(get_neighbor(a, id[i, 1], id[i, 2]), na.rm = T)
if(is.nan(a[id[i, 1], id[i, 2]])){a[id[i, 1], id[i, 2]] <- NA}
}
#print(a)
id <- which(is.na(a), arr.ind = T)
id <- data.frame(cbind(id, rep(0, nrow(id))))
}
}
return(a)
}
example
a <- matrix(data = runif(100, 0, 10), ncol = 10, nrow = 10)
a[a<2] <- NA
a
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 2.313512 NA 5.311104 2.832978 9.917106 2.734799 7.309386 NA 4.794476 6.479147
[2,] 8.855676 7.555101 8.369477 6.346744 7.727896 NA 9.019421 5.061894 9.116066 6.732293
[3,] 2.948539 7.440258 6.918414 2.155361 3.511407 5.601253 NA 6.561557 9.543535 4.082592
[4,] 8.455382 9.169974 NA 4.978224 6.202393 NA 9.435753 9.411371 NA 2.128417
[5,] 7.744456 3.333072 6.975128 5.876849 4.044768 2.948399 5.067653 NA 6.039412 7.350782
[6,] 8.793417 9.683755 8.053603 7.406450 6.348171 3.122946 9.378282 5.808363 7.923061 6.415419
[7,] 4.759612 3.431247 4.123641 6.899569 4.464683 6.588431 5.985248 7.962148 6.668238 4.503556
[8,] 5.992242 NA 7.099657 6.446650 NA 8.448873 5.884961 NA 2.209453 8.103988
[9,] 6.383036 NA NA 5.499157 6.972433 3.129470 3.284383 9.150565 8.484186 4.672878
[10,] NA NA 4.258936 NA 9.015525 NA NA NA NA 6.639832
nn_mean(a)
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 2.313512 6.480974 5.311104 2.832978 9.917106 2.734799 7.309386 7.060248 4.794476 6.479147
[2,] 8.855676 7.555101 8.369477 6.346744 7.727896 6.545895 9.019421 5.061894 9.116066 6.732293
[3,] 2.948539 7.440258 6.918414 2.155361 3.511407 5.601253 7.111993 6.561557 9.543535 4.082592
[4,] 8.455382 9.169974 5.855910 4.978224 6.202393 5.258804 9.435753 9.411371 6.587278 2.128417
[5,] 7.744456 3.333072 6.975128 5.876849 4.044768 2.948399 5.067653 7.580556 6.039412 7.350782
[6,] 8.793417 9.683755 8.053603 7.406450 6.348171 3.122946 9.378282 5.808363 7.923061 6.415419
[7,] 4.759612 3.431247 4.123641 6.899569 4.464683 6.588431 5.985248 7.962148 6.668238 4.503556
[8,] 5.992242 5.298239 7.099657 6.446650 6.056158 8.448873 5.884961 6.203648 2.209453 8.103988
[9,] 6.383036 5.902524 5.834195 5.499157 6.972433 3.129470 3.284383 9.150565 8.484186 4.672878
[10,] 6.383036 5.731883 4.258936 6.436513 9.015525 5.600453 5.291218 6.689444 7.236865 6.639832
some idea or a function that is efficient?

This can be written in a even short and fast way in R:
nn_impute <- function(dat){
idx <- which(is.na(dat), TRUE)
impute <- function(x){
y <- expand.grid(x[1] + c(-1,0,1), x[2] + c(-1,0,1))
z <- !(y == 0 | y > nrow(dat) | y> ncol(dat))
mean(dat[as.matrix(y[rowSums(z) == 2,])], na.rm = TRUE)
}
dat[idx] <- apply(idx, 1, impute)
dat
}
nn_impute(a) ## Returns the filled in values
This code is around 38X faster than the provided code

I kept your code above, apart from nn_mean function, I defined an nn_mean2 function.
It works about 20x times faster than yours, but gives different results. Since I don't know why you wrote your function the way you did, i.e. your requirements, I can't tell why my approach is not suitable. but it is way faster. It naively uses your get_neighbour definition, averages the found neighbour values and substitutes them into the holes. You must be needing to do something else or our results would have matched I would have thought.
Here it is for consideration
nn_mean2 <- function(a){
res2 <- a
# get the missings
list_of_missing <- which(is.na(a))
list_of_missing_df <- data.frame(which(is.na(a),arr.ind = TRUE))
list_of_missing_df$missing_fills <- purrr::map_dbl(seq_len(nrow(list_of_missing_df)),
~{
mean(get_neighbor(a,
x=list_of_missing_df$row[.x],
y=list_of_missing_df$col[.x]),
na.rm=TRUE)
})
res2[list_of_missing] <- list_of_missing_df$missing_fills
res2
}
res2 <- nn_mean2(a)
microbenchmark::microbenchmark(n1 = nn_mean(a),
n2=nn_mean2(a))
# A tibble: 2 x 13
expression min median `itr/sec` mem_al~1 gc/se~2 n_itr n_gc total~3 result memory
<bch:expr> <bch:tm> <bch:tm> <dbl> <bch:by> <dbl> <int> <dbl> <bch:t> <list> <list>
1 n1 380ms 425ms 2.35 107.34MB 4.71 2 4 850ms <NULL> <Rprofmem>
2 n2 17ms 20.1ms 39.9 6.91MB 5.99 20 3 501ms <NULL> <Rprofmem>
# see the difference in values though
res1 - res2

Related

Conditionally update rast values from another raster using terra

I am using the lapp functin of {terra} in R and I want to update rast_a with values from rast_b or rast_c (and some other math) depending on the value in each cell of rast_a.
sample data
rast_a <- rast(ncol = 2, nrow = 2)
values(rast_a) <- 1:4
rast_b <- rast(ncol = 2, nrow = 2)
values(rast_b) <- c(2,2,2,2)
rast_c <- rast(ncol = 2, nrow = 2)
values(rast_c) <- c(3,3,3,3)
Problem
This is my (wrong) attempt.
my_update_formula <- function(a, b, c) {
a[a == 1] <- b[a == 1] + 10 + 20 - 30
a[a == 2] <- c[a == 2] + 10 + 50 - 50
return(a)
}
result <- lapp(c(rast_a, rast_b, rast_c),
fun = my_update_formula)
values(result)
lyr1
[1,] 3
[2,] 3
[3,] 3
[4,] 4
The actual result should be 2,3,3,4. But because of the operations inside the formula, the first value gets updated twice. First it is changed from 1 to 2 (correctly) but then it fulfills the condition of the second line of code also, and is changed again (I don't want that to happen).
How can I solve this please?
You can change your formula to
f1 <- function(a, b, c) {
d <- a
d[a == 1] <- b[a == 1]
d[a == 2] <- c[a == 2] + 10
d
}
#or
f2 <- function(a, b, c) {
i <- a == 1
j <- a == 2
a[i] <- b[i]
a[j] <- c[j] + 10
return(a)
}
lapp(c(rast_a, rast_b, rast_c), fun = f1) |> values()
# lyr1
#[1,] 2
#[2,] 13
#[3,] 3
#[4,] 4
lapp(c(rast_a, rast_b, rast_c), fun = f2) |> values()
# lyr1
#[1,] 2
#[2,] 13
#[3,] 3
#[4,] 4
You can get the same result with
x <- ifel(rast_a==1, rast_b,
ifel(rast_a == 2, rast_c + 10, rast_a))

R_Extract the row and column of the element in use when using apply function

How to extract the row and column of the element in use when using apply function? For example, say I want to apply a function for each element of the matrix where row and column number of the selected element are also variables in the function. A simple reproducible example is given below
mymatrix <- matrix(1:12, nrow=3, ncol=4)
I want a function which does the following
apply(mymatrix, c(1,2), function (x) sum(x, row_number, col_number))
where row_number and col_number are the row and column number of the selected element in mymatrix. Note that my function is more complicated than sum, so a robust solution is appreciated.
I'm not entirely sure what you're trying to do but I would use a for loop here.
Pre-allocate the return matrix and this will be very fast
ret <- mymatrix
for (i in 1:nrow(mymatrix))
for (j in 1:ncol(mymatrix))
ret[i, j] <- sum(mymatrix[i, j], i, j)
# [,1] [,2] [,3] [,4]
#[1,] 3 7 11 15
#[2,] 5 9 13 17
#[3,] 7 11 15 19
Benchmark analysis 1
I was curious so I ran a microbenchmark analysis to compare methods; I used a bigger 200x300 matrix.
mymatrix <- matrix(1:600, nrow = 200, ncol = 300)
library(microbenchmark)
res <- microbenchmark(
for_loop = {
ret <- mymatrix
for (i in 1:nrow(mymatrix))
for (j in 1:ncol(mymatrix))
ret[i, j] <- sum(mymatrix[i, j], i, j)
},
expand_grid_mapply = {
newResult<- mymatrix
grid1 <- expand.grid(1:nrow(mymatrix),1:ncol(mymatrix))
newResult[]<-
mapply(function(row_number, col_number){ sum(mymatrix[row_number, col_number], row_number, col_number) },row_number = grid1$Var1, col_number = grid1$Var2 )
},
expand_grid_apply = {
newResult<- mymatrix
grid1 <- expand.grid(1:nrow(mymatrix),1:ncol(mymatrix))
newResult[]<-
apply(grid1, 1, function(x){ sum(mymatrix[x[1], x[2]], x[1], x[2]) })
},
double_sapply = {
sapply(1:ncol(mymatrix), function (x) sapply(1:nrow(mymatrix), function (y) sum(mymatrix[y,x],x,y)))
}
)
res
#Unit: milliseconds
# expr min lq mean median uq max
# for_loop 41.42098 52.72281 56.86675 56.38992 59.1444 82.89455
# expand_grid_mapply 126.98982 161.79123 183.04251 182.80331 196.1476 332.94854
# expand_grid_apply 295.73234 354.11661 375.39308 375.39932 391.6888 562.59317
# double_sapply 91.80607 111.29787 120.66075 120.37219 126.0292 230.85411
library(ggplot2)
autoplot(res)
Benchmark analysis 2 (with expand.grid outside of microbenchmark)
grid1 <- expand.grid(1:nrow(mymatrix),1:ncol(mymatrix))
res <- microbenchmark(
for_loop = {
ret <- mymatrix
for (i in 1:nrow(mymatrix))
for (j in 1:ncol(mymatrix))
ret[i, j] <- sum(mymatrix[i, j], i, j)
},
expand_grid_mapply = {
newResult<- mymatrix
newResult[]<-
mapply(function(row_number, col_number){ sum(mymatrix[row_number, col_number], row_number, col_number) },row_number = grid1$Var1, col_number = grid1$Var2 )
},
expand_grid_apply = {
newResult<- mymatrix
newResult[]<-
apply(grid1, 1, function(x){ sum(mymatrix[x[1], x[2]], x[1], x[2]) })
}
)
res
#Unit: milliseconds
# expr min lq mean median uq max
# for_loop 39.65599 54.52077 60.87034 59.19354 66.64983 95.7890
# expand_grid_mapply 130.33573 167.68201 194.39764 186.82411 209.33490 400.9273
# expand_grid_apply 296.51983 373.41923 405.19549 403.36825 427.41728 597.6937
That's not how apply works: You cannot access the current index (row, col index) from inside [lsvm]?apply-family.
You will have to create the current row and col index before applying. ?expand.grid.
mymatrix <- matrix(1:12, nrow=3, ncol=4)
newResult<- mymatrix
grid1 <- expand.grid(1:nrow(mymatrix),1:ncol(mymatrix))
newResult[]<-
mapply(function(row_number, col_number){ sum(mymatrix[row_number, col_number], row_number, col_number) },row_number = grid1$Var1, col_number = grid1$Var2 )
newResult
# [,1] [,2] [,3] [,4]
#[1,] 3 7 11 15
#[2,] 5 9 13 17
#[3,] 7 11 15 19
If you want to use apply
newResult[]<-
apply(grid1, 1, function(x){ sum(mymatrix[x[1], x[2]], x[1], x[2]) })
This is my thought with outer() function.
The third argument FUN can be any two-argument function.
mymatrix <- matrix(1:12, nrow = 3, ncol = 4)
nr <- nrow(mymatrix)
nc <- ncol(mymatrix)
mymatrix + outer(1:nr, 1:nc, FUN = "+")
[,1] [,2] [,3] [,4]
[1,] 3 7 11 15
[2,] 5 9 13 17
[3,] 7 11 15 19
With #Maurits Evers' benchmark code :
Unit: microseconds
expr min lq mean median uq max
for_loop 19963.203 22427.1630 25308.168 23811.855 25017.031 158341.678
outer 848.247 949.3515 1054.944 1011.457 1059.217 1463.956
In addition, I try to complete your original idea with apply(X, c(1,2), function (x)) :
(It's a little slower than other answers)
mymatrix <- matrix(1:12, nrow = 3, ncol = 4)
n <- 1 # n = index of data
nr <- nrow(mymatrix)
apply(mymatrix, c(1,2), function (x) {
row_number <- (n-1) %% nr + 1 # convert n to row number
col_number <- (n-1) %/% nr + 1 # convert n to column number
res <- sum(x, row_number, col_number)
n <<- n + 1
return(res)
})
[,1] [,2] [,3] [,4]
[1,] 3 7 11 15
[2,] 5 9 13 17
[3,] 7 11 15 19

Loop for Stochastic equations

I would like to generate a sequence of stochastic equations for 100 different seed using the following expression:
set.seed(123)
N <- 100
T <- 1
x <- 10
theta <- c (0 , 5 , 3.5)
Dt <- 1 /N
Y <- numeric (N +1)
Y [1] <- x
Z <- rnorm (N)
for (i in 1: N)
{Y[ i +1] <- Y[ i] + ( theta [1] - theta [2] * Y[ i ]) * Dt + theta [3] * sqrt ( Dt ) *Z [i ]
Y <- ts (Y , start =0 , deltat =1 /N )
Finally, I want to save the 100 "Y" time series into a matrix.
How can I create a loop that save every value for "Y" time series?
If you use replicate as a wrapper around that code as I suggested you will need to put in an additional reference to the Y variable outside the for-loop. Replicate naturally returns a matrix. Using 10 rather than 100 for testing:
set.seed(123)
N=10
> rep.mtx <- replicate( 10, {
+ T <- 1
+ x <- 10
+ theta <- c (0 , 5 , 3.5)
+ Dt <- 1 /N
+ Y <- numeric (N +1)
+ Y [1] <- x
+ Z <- rnorm (N)
+ for (i in 1: N)
+ {Y[ i +1] <- Y[ i] + ( theta [1] - theta [2] * Y[ i ]) * Dt + theta [3] * sqrt ( Dt ) *Z [i ]
+ Y <- ts(Y , start =0 , deltat =1 /N ) } ; Y} )
> rep.mtx
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 10.0000000 10.000000000 10.00000000 10.000000000 10.00000000 10.0000000 10.0000000 10.00000000 10.0000000 10.0000000
[2,] 4.3796671 6.354810283 3.81813573 5.472009398 4.23110027 5.2803722 5.4201839 4.45652809 5.0063798 6.0996073
[3,] 1.9350738 3.575646071 1.66781385 2.409420413 1.88542788 2.6085906 2.1541218 -0.32751756 2.9296172 3.6567678
[4,] 2.6927109 2.231395747 -0.30167191 2.195432765 -0.45782317 1.2568464 0.7082679 0.94938979 1.0545631 2.0926115
[5,] 1.4243939 1.238201192 -0.95757071 2.069632051 2.17168276 2.1431884 -0.7732224 -0.31024651 1.2404757 0.3513411
[6,] 0.8552923 0.003897195 -1.17057706 1.944139651 2.42281031 0.8217115 -1.5728667 -0.91660925 0.3762039 1.6816368
[7,] 2.3258752 1.979699020 -2.45211593 1.734254917 -0.03164826 2.0892811 -0.4504887 0.67679487 0.5553173 0.1764528
[8,] 1.6730784 1.540869016 -0.29879763 1.480201956 -0.46173593 -0.6695147 0.2708330 0.02321148 1.4916370 2.5091604
[9,] -0.5636270 -1.406211817 0.02035412 0.671577271 -0.74736079 0.3122915 0.1940814 -1.33948118 1.2274761 2.9508693
[10,] -1.0420203 0.073152826 -1.24950969 -0.002849978 0.48958280 0.2932273 1.1178037 -0.46907441 0.2529979 1.2145622
[11,] -1.0142676 -0.486707784 0.76296397 -0.422529220 0.15251875 0.3856172 2.8279298 -0.38826177 1.3979960 -0.5287587

R performance power function

Anyone has a tip how to speed up the code below? Particularly with avoiding the for-loops?
J <- 10000
I <- 10000
Y <- matrix(0,J,I)
X <- runif(I,0,1)
P <- runif(I,0,1)
Z <- matrix(runif(n = J*I,0,1),J,I)
K <- matrix(runif(n = J*I,0,1),J,I)
for(j in 1:J){
for (i in 1:I){
Y[j,i] <- X[i]^(Z[j,i])*P[i]^(K[j,i])
}
}
Thanks!
I think t(X^t(Z)*P^t(K)) would lead to the same result and much faster. Here is a reproducible example with a 5 X 5 matrix and performance evaluation.
set.seed(543)
### Original Code
J <- 5
I <- 5
Y <- matrix(0,J,I)
X <- runif(I,0,1)
P <- runif(I,0,1)
Z <- matrix(runif(n = J*I,0,1),J,I)
K <- matrix(runif(n = J*I,0,1),J,I)
for(j in 1:J){
for (i in 1:I){
Y[j,i] <- X[i]^(Z[j,i])*P[i]^(K[j,i])
}
}
# View the result
Y
# [,1] [,2] [,3] [,4] [,5]
# [1,] 0.8244760 0.7717289 0.3884273 0.30937614 0.6807137
# [2,] 0.8878758 0.3761184 0.2819624 0.08388850 0.5299624
# [3,] 0.9559749 0.7813653 0.2048310 0.05117558 0.4069641
# [4,] 0.9317235 0.6614524 0.1619824 0.08777542 0.3037913
# [5,] 0.9507279 0.5434549 0.3950076 0.08050582 0.3244810
### A solution without for loop
Y2 <- t(X^t(Z)*P^t(K))
# View the result
Y2
# [,1] [,2] [,3] [,4] [,5]
# [1,] 0.8244760 0.7717289 0.3884273 0.30937614 0.6807137
# [2,] 0.8878758 0.3761184 0.2819624 0.08388850 0.5299624
# [3,] 0.9559749 0.7813653 0.2048310 0.05117558 0.4069641
# [4,] 0.9317235 0.6614524 0.1619824 0.08777542 0.3037913
# [5,] 0.9507279 0.5434549 0.3950076 0.08050582 0.3244810
identical(Y, Y2)
# [1] TRUE
### Performance evaluation
library(microbenchmark)
perf <- microbenchmark(
m1 = { Y <- matrix(0,J,I)
for(j in 1:J){
for (i in 1:I){
Y[j,i] <- X[i]^(Z[j,i])*P[i]^(K[j,i])
}
}},
m2 = {Y2 <- t(X^t(Z)*P^t(K))},
times = 100L
)
# View the result
perf
# Unit: microseconds
# expr min lq mean median uq max neval cld
# m1 3649.287 3858.250 4107.31032 3932.017 4112.965 6240.644 100 b
# m2 13.365 14.907 21.66753 15.422 26.731 60.658 100 a

Conditional collapse of matrix rows with custom function

I want to collapse rows in a matrix so that no value of a particular column ever falls below 20. And I want to apply a custom function to the rows to collapse/sum them...
Here is an example matrix:
d <- matrix(data = c(0,105,1,21,2,11,4,5,5,15,7,21,9,1),
ncol = 2,
byrow = TRUE
)
colnames(d) <- c('val','freq')
Looking like this:
d
val freq
[1,] 0 105
[2,] 1 21
[3,] 2 11
[4,] 4 5
[5,] 5 15
[6,] 7 21
[7,] 9 1
The column where the cells must be 20 or above is "freq". So row 1 and 2 are fine, but I need to collapse row 3:5. And I want to replace row 3:5 with the single row from this function:
library(reshape)
replacement <- function(x){
mat <- d[x, ]
mat.res <- untable(mat[ ,c(1, 2)],
num = mat[ ,2]
)
res <- c(mean(mat.res[ ,1]), length(mat.res[ ,1]))
return(res)
}
The function call:
replacement(3:5)
[1] 3.774194 31.000000
Going through the matrix; row 6 is fine, but since row 7 would be left with freq=1 this row needs to be collapsed with row 6. The function call again:
replacement(6:7)
[1] 7.090909 22.000000
The resulting matrix should be:
val freq
[1,] 0 105
[2,] 1 21
[3,] 3.774194 31.000000
[4,] 7.090909 22.000000
The final row numbering is not important.
I have a feeling that the window functions of dplyr might hold the solution, but I need help understanding exactly how. It does not have to be dplyr. I take whatever works ;-)
For future reference, this is not very elegant, but it works...
rows <- dim(d)[1]
tmp <- NULL
inc <- 1
tmpSum <- 0
for(i in 1:rows){
if(d[i, 2] > 19){
tmp <- rbind(tmp, c(d[i, ], inc))
inc <- inc + 1
tmpSum <- 0
} else {
tmp <- rbind(tmp, c(d[i, ], inc))
tmpSum <- d[i,2] + tmpSum
if(tmpSum > 19){
inc <- inc + 1
}
}
}
if(sum(tmp[tmp[ ,3] == max(tmp[ ,3]), 2]) < 19){
tmp[tmp[ ,3] == max(tmp[ ,3]), 3] <- tmp[tmp[ ,3] == max(tmp[ ,3]), 3]-1
}
res <- NULL
for(i in 1:max(tmp[ ,3])){
val <- mean(rep(tmp[tmp[ ,3] == i, 1], tmp[tmp[ ,3] == i, 2]))
freq <- length(rep(tmp[tmp[ ,3] == i, 1], tmp[tmp[ ,3] == i, 2]))
res <- rbind(res, c(val, freq))
}
res

Resources