Constructing a randomised matrix with no duplicates but fixed partial input - r

I´m facing a problem with constructing a randomised matrix where I partially already have values (that need to stay fixed - so no further randomisation there).
Lets see:
matrix should end up being 10 by 10
n <- 10
I do want my first rows to be the data I enter. e.g:
row1<- c(1,4,7,6,5,3,2,8,9,10)
row2<- c(10,7,3,2,1,4,5,9,8,6)
row3<- c(9,2,4,3,8,7,10,1,6,5)
To bild a matrix with 10 rows (and 10 columns) I combined those rows with samples (no replace because I want each number to be unique in each row).
first.rows<-rbind(row1,row2,row3,sample(n,n,replace=F),sample(n,n,replace=F),sample(n,n,replace=F),sample(n,n,replace=F),sample(n,n,replace=F),sample(n,n,replace=F),sample(n,n,replace=F))
output:
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
row1 1 4 7 6 5 3 2 8 9 10
row2 10 7 3 2 1 4 5 9 8 6
row3 9 2 4 3 8 7 10 1 6 5
6 1 5 4 2 10 3 8 7 9
2 5 7 8 9 6 1 3 4 10
10 6 4 1 8 3 7 2 5 9
8 5 3 2 4 1 10 7 6 9
10 7 9 6 8 2 5 4 3 1
1 10 8 4 7 3 5 2 6 9
2 1 10 4 8 9 3 6 5 7
So far so good..
However now I have the problem that there is no control for unique numbers in the columns. This is what I would need though. I get that this the case because I used rbind (and therefore only the function of no duplicates only works for the rows). But I do not know how else to approach this problem. The rows 1-3 should stay exactly as they are now.
Any ideas?

I think my previous solution Fixed values not repeated over column and row can be modified to work. You need a solver, but instead of starting with a empty grid, it starts with a pre-filled matrix:
# x is your matrix, "not filled" values should be NA
# x is a square matrix with dimension n (big n will take longer to converge)
backtrack = function(x){
n = ncol(x)
stopifnot(ncol(x)==nrow(x))
cells = list()
k = 1
for (i in 1:n){
for (j in 1:n){
if (is.na(x[i, j]))
cells[[k]] = sample(1:n)
else
cells[[k]] = NULL
k = k + 1
}
}
i = 0
while (i < n*n){
if (is.null(cells[[i+1]])){
i=i+1
next
}
candidates = cells[[i + 1]]
idx = sample(1:length(candidates), 1)
val = candidates[idx]
if (length(candidates) == 0){
cells[[i + 1]] = sample(1:n)
i = i - 1
x[as.integer(i/n) + 1, i %% n + 1] = NA
}
else {
rr = as.integer(i/n) + 1
cc = i %% n + 1
if ((val %in% x[rr, ]) || (val %in% x[, cc])){
candidates = candidates[-idx]
cells[[i + 1]] = candidates
}
else{
x[as.integer(i/n) + 1, i %% n + 1] = val
candidates = candidates[-idx]
cells[[i + 1]] = candidates
i = i + 1
}
}
}
x
}
Empty initial matrix
set.seed(1)
x = backtrack(matrix(NA, nrow = 10, ncol = 10))
print(x)
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 8 10 4 6 9 7 1 2 3 5
[2,] 5 6 9 8 1 10 4 3 2 7
[3,] 10 7 1 2 8 9 5 4 6 3
[4,] 3 9 8 10 6 5 7 1 4 2
[5,] 9 1 6 4 7 3 2 5 10 8
[6,] 1 4 10 3 2 6 8 7 5 9
[7,] 2 8 5 9 10 1 3 6 7 4
[8,] 6 5 2 7 3 4 10 9 8 1
[9,] 4 3 7 1 5 2 6 8 9 10
[10,] 7 2 3 5 4 8 9 10 1 6
Pre-filled initial matrix
m = matrix(NA, ncol = 10, nrow = 10)
m[1, ] = c(1,4,7,6,5,3,2,8,9,10)
m[2, ] = c(10,7,3,2,1,4,5,9,8,6)
m[3, ] = c(9,2,4,3,8,7,10,1,6,5)
x = backtrack(m)
print(x)
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 1 4 7 6 5 3 2 8 9 10
[2,] 10 7 3 2 1 4 5 9 8 6
[3,] 9 2 4 3 8 7 10 1 6 5
[4,] 5 9 6 8 3 2 4 7 10 1
[5,] 7 1 5 10 9 6 3 2 4 8
[6,] 2 5 8 1 10 9 6 3 7 4
[7,] 6 3 1 4 7 5 8 10 2 9
[8,] 8 10 9 5 4 1 7 6 3 2
[9,] 3 6 10 9 2 8 1 4 5 7
[10,] 4 8 2 7 6 10 9 5 1 3
NOTE: I didn't tested it for bugs.

Related

Create new vectors with no element being in the same position as the original vector as well as with other vectors?

This question is an extension of a question I asked earlier.
Suppose I have a vector V1 (with two or more elements):
V1 <- 1:10
I want to sample one or several vectors that:
(1). no element is in the same position as the original vector.
(2). no element is in the same position among the new vectors.
The following two are such vectors:
9 4 7 1 2 5 3 10 6 8
5 7 4 2 3 8 9 6 10 1
Here is one way to do this :
#Define the vector
V1 <- 1:10
#Number of rows
n <- 7
#Create a matrix with the vector `V1` in each row
mat <- matrix(V1, ncol = length(V1), nrow = n, byrow = TRUE)
i <- 2
while(i <= n) {
#Get randomised V1
temp <- sample(V1)
#Check if any of the previous row does not have the same combination
if (all(colSums(t(t(mat) == temp)) == 0)) {
#Add the random vector in the matrix
mat[i, ] <- temp
i <- i + 1
}
}
mat
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
#[1,] 1 2 3 4 5 6 7 8 9 10
#[2,] 4 5 6 7 10 2 1 9 3 8
#[3,] 2 6 7 9 1 3 8 10 5 4
#[4,] 9 3 1 2 4 8 6 5 10 7
#[5,] 7 8 5 3 6 9 10 4 1 2
#[6,] 3 1 4 5 8 10 9 7 2 6
#[7,] 8 4 2 10 9 1 5 6 7 3

how to assign the size of 2-D matrix to two new variable in r?

This is what I know in Matlab and want do same in r programming
A=[1 2 3;4 5 6; 7 8 9];
A =
1 2 3
4 5 6
7 8 9
[m,n]=size(A)
m=3
n=3
so here I have two distinct variables to which the dimension or size of 2D matrix is assigned automatically
> x<-c(1:10)
> x
[1] 1 2 3 4 5 6 7 8 9 10
> A=matrix(0,10,10)
> A=Toeplitz(x,c(x[1],rev(x[-1])))
> A
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 1 10 9 8 7 6 5 4 3 2
[2,] 2 1 10 9 8 7 6 5 4 3
[3,] 3 2 1 10 9 8 7 6 5 4
[4,] 4 3 2 1 10 9 8 7 6 5
[5,] 5 4 3 2 1 10 9 8 7 6
[6,] 6 5 4 3 2 1 10 9 8 7
[7,] 7 6 5 4 3 2 1 10 9 8
[8,] 8 7 6 5 4 3 2 1 10 9
[9,] 9 8 7 6 5 4 3 2 1 10
[10,] 10 9 8 7 6 5 4 3 2 1
> n=size(A)
> n
[1] 10 10
>[ m,n]=size(A)
this is not working so is there any way to assign the size of the 2Dmatrix to two distinct variable m and n in r.I am learning r programming and need help

How can I find repeated values/ data points and their index in 2D matrix of a dataframe in R?

For example suppose I have matrix A
x y z f
1 1 2 A 1005
2 2 4 B 1002
3 3 2 B 1001
4 4 8 C 1001
5 5 10 D 1004
6 6 12 D 1004
7 7 11 E 1005
8 8 14 E 1003
From this matrix I want to find the repeated values like 1001, 1005, D, 2 (in third column) and I also want to find their index (which row, or which position).
I am new to R!
Obviously it is possible to do with simple searching element by element by using a for loop, but I want to know, is there any function available in R for this kind of problem.
Furthermore, I tried using duplicated and unique, both functions are giving me the duplicated row number or column number, they are also giving me how many of them were repeated, but I can not search for whole matrix using both of them!
You can write a rather simple function to get this information. Though note that this solution works with a matrix. It does not work with a data.frame. A similar function could be written for a data.frame using the fact that the data.frame data structure is a subset of a list.
# example data
set.seed(234)
m <- matrix(sample(1:10, size=100, replace=T), 10)
find_matches <- function(mat, value) {
nr <- nrow(mat)
val_match <- which(mat == value)
out <- matrix(NA, nrow= length(val_match), ncol= 2)
out[,2] <- floor(val_match / nr) + 1
out[,1] <- val_match %% nr
return(out)
}
R> m
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 8 6 6 7 6 7 4 10 6 9
[2,] 8 6 6 3 10 4 5 4 6 9
[3,] 1 6 9 2 9 2 3 6 4 2
[4,] 8 6 7 8 3 9 9 4 9 2
[5,] 1 1 5 6 7 1 5 1 10 6
[6,] 7 5 4 7 8 2 4 4 7 10
[7,] 10 4 7 8 3 1 8 6 3 4
[8,] 8 8 2 2 7 5 6 4 10 4
[9,] 10 2 9 6 6 9 7 2 4 7
[10,] 3 9 9 4 2 7 7 2 9 6
R> find_matches(m, 8)
[,1] [,2]
[1,] 1 1
[2,] 2 1
[3,] 4 1
[4,] 8 1
[5,] 8 2
[6,] 4 4
[7,] 7 4
[8,] 6 5
[9,] 7 7
In this function, the row index is output in column 1 and the column index is output in column 2

Creating matrix of colnumbers from a vector

Let's say, I have a vector of size 10. How do I create a matrix with position of vector elements arranged like this.
1 2 3 4 5 6 7 8 9 10
2 3 4 5 6 7 8 9 10 1
3 4 5 6 7 8 9 10 1 2
4 5 6 7 8 9 10 1 2 3
5 6 7 8 9 10 1 2 3 4
6 7 8 9 10 1 2 3 4 5
7 8 9 10 1 2 3 4 5 6
8 9 10 1 2 3 4 5 6 7
9 10 1 2 3 4 5 6 7 8
10 1 2 3 4 5 6 7 8 9
You could:
x = 1:10
matrix(x, nrow = length(x), ncol = length(x) + 1, byrow = T)[, -(length(x) + 1)]
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
# [1,] 1 2 3 4 5 6 7 8 9 10
# [2,] 2 3 4 5 6 7 8 9 10 1
# [3,] 3 4 5 6 7 8 9 10 1 2
# [4,] 4 5 6 7 8 9 10 1 2 3
# [5,] 5 6 7 8 9 10 1 2 3 4
# [6,] 6 7 8 9 10 1 2 3 4 5
# [7,] 7 8 9 10 1 2 3 4 5 6
# [8,] 8 9 10 1 2 3 4 5 6 7
# [9,] 9 10 1 2 3 4 5 6 7 8
#[10,] 10 1 2 3 4 5 6 7 8 9
As #flodel noted in the comments, you could, also, build the matrix with an extra row and remove it. And, also, use nicer format: head(matrix(x, nrow = length(x) + 1 , ncol = length(x)), -1).
How about this?
sapply(1:10, function(idx){
vec <- 1:10
if(idx != 1){
vec <- c(vec[idx:10], 1:(idx-1))
}
vec
}
)

to find most frequently occuring element in matrix in R

Is there any function in R to find most frequently occuring element in matrix??I Have a matrix containing image pixels.I want to find which image pixel occur most frequently in the image matrix.I dont want to use the for loops since it would be very time taking to iterate over all the pixels of an image.
Set up some test data.
> (image = matrix(sample(1:10, 100, replace = TRUE), nrow = 10))
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 4 4 2 7 2 2 3 8 2 5
[2,] 7 3 2 6 6 5 7 8 1 3
[3,] 7 5 7 9 4 9 4 8 2 7
[4,] 5 3 4 2 1 5 9 10 9 5
[5,] 9 10 7 2 7 4 9 1 1 9
[6,] 2 3 5 1 2 8 1 5 9 4
[7,] 5 4 10 5 9 10 1 6 1 10
[8,] 6 3 9 7 1 1 9 2 1 7
[9,] 5 9 4 8 9 9 5 10 5 4
[10,] 10 1 4 7 3 2 3 5 4 5
Do it manually.
> table(image)
image
1 2 3 4 5 6 7 8 9 10
12 12 8 12 15 4 11 5 14 7
Here we can see that the value 5 appeared most often (15 times). To get the same results programmatically:
> which.max(table(image))
5
5
Get mode (or majority value) in 1 line of code
using set.seed to generate same random matrix
> set.seed(123)
> image = matrix(sample(1:10, 100, replace = TRUE), nrow = 10)
> image
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 3 10 9 10 2 1 7 8 3 2
[2,] 8 5 7 10 5 5 1 7 7 7
[3,] 5 7 7 7 5 8 4 8 5 4
[4,] 9 6 10 8 4 2 3 1 8 7
[5,] 10 2 7 1 2 6 9 5 2 4
[6,] 1 9 8 5 2 3 5 3 5 2
[7,] 6 3 6 8 3 2 9 4 10 8
[8,] 9 1 6 3 5 8 9 7 9 1
[9,] 6 4 3 4 3 9 8 4 9 5
[10,] 5 10 2 3 9 4 5 2 2 6)
Mode value of matrix (if tie, its gives minimum tie value)
> names(which.max(table(image)))
[1] "5"
I do not know any function to do that directly but you can use these functions:
sort(table(as.vector(Matrix))

Resources