Creating matrix based on knowing the dimensions in a pattern - r

I tried to solve a problem programmatically, but was unsuccessful. Here are some of the the examples to generate
cbind(1:12,13:2,3:14,15:4,5:16,17:6,7:18,19:8,9:20,21:10)
cbind(1:11,12:2,3:13,14:4,5:15,16:6,7:17,18:8,9:19)
Looking for a general solution for this problem. If the number of columns and rows are given, the program should output the matrix. Thanks.

You can do it fairly easily using apply. Just generate the matrix columns counting y steps up from the column number, and reverse the even columns;
> x=5; y=7
> apply(t(1:x), 2, function(x) if(x%%2) x-1+1:y else x-1+y:1)
[,1] [,2] [,3] [,4] [,5]
[1,] 1 8 3 10 5
[2,] 2 7 4 9 6
[3,] 3 6 5 8 7
[4,] 4 5 6 7 8
[5,] 5 4 7 6 9
[6,] 6 3 8 5 10
[7,] 7 2 9 4 11

m = embed(1:19, 9)
m[, seq(2, ncol(m), by=2)] = m[nrow(m):1, seq(2, ncol(m), by=2)]
m[,ncol(m):1]
produces
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
[1,] 1 12 3 14 5 16 7 18 9
[2,] 2 11 4 13 6 15 8 17 10
[3,] 3 10 5 12 7 14 9 16 11
[4,] 4 9 6 11 8 13 10 15 12
[5,] 5 8 7 10 9 12 11 14 13
[6,] 6 7 8 9 10 11 12 13 14
[7,] 7 6 9 8 11 10 13 12 15
[8,] 8 5 10 7 12 9 14 11 16
[9,] 9 4 11 6 13 8 15 10 17
[10,] 10 3 12 5 14 7 16 9 18
[11,] 11 2 13 4 15 6 17 8 19

Related

Unable to store values in a numeric array inside for loop

I am trying to store values into a numeric array using a sliding window. However, I am not able to store values using the following code -
d=c(1:1000)
e=0
for (i in d){
a[e]=c(i:i+10)
e=e+1
}
I am looking to see -
a[1]=1 2 3 4 5 6 7 8 9 10
a[2]=2 3 4 5 6 7 8 9 10 11
You might use embed and then apply to reverse each row
x <- 1:20
t(apply(embed(x, 10), 1, rev))
# [,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 11
# [3,] 3 4 5 6 7 8 9 10 11 12
# [4,] 4 5 6 7 8 9 10 11 12 13
# [5,] 5 6 7 8 9 10 11 12 13 14
# [6,] 6 7 8 9 10 11 12 13 14 15
# [7,] 7 8 9 10 11 12 13 14 15 16
# [8,] 8 9 10 11 12 13 14 15 16 17
# [9,] 9 10 11 12 13 14 15 16 17 18
#[10,] 10 11 12 13 14 15 16 17 18 19
#[11,] 11 12 13 14 15 16 17 18 19 20
This might be a faster option of the same idea
out <- embed(x, 10)
out[, ncol(out):1]
Returning a list:
first <- c(0:9)
a <-lapply(1:1000, function(x) first+x)
a[1] 1 2 3 4 5 6 7 8 9 10
a[2] 2 3 4 5 6 7 8 9 10 11
a[3] 3 4 5 6 7 8 9 10 11 12
Does it need to be an array? The following makes a matrix:
sapply(1:10, function(i) i:(i+10))
This may work depending on the downstream application. If it has to be an array, check out How to convert matrix into array?
[,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 11
[3,] 3 4 5 6 7 8 9 10 11 12
[4,] 4 5 6 7 8 9 10 11 12 13
[5,] 5 6 7 8 9 10 11 12 13 14
[6,] 6 7 8 9 10 11 12 13 14 15
[7,] 7 8 9 10 11 12 13 14 15 16
[8,] 8 9 10 11 12 13 14 15 16 17
[9,] 9 10 11 12 13 14 15 16 17 18
[10,] 10 11 12 13 14 15 16 17 18 19
[11,] 11 12 13 14 15 16 17 18 19 20

Matrix function in R

I'm trying to create a function that will transform a matrix (MATR1). It should multiply every element that is a prime by 2 and return the new matrix (MATR2). This is what I've done so far:
MATR1 <- matrix()
My.Func <- function(MATR1)
MATR2 <- matrix(nrow(MATR1), ncol(MATR1))
for (i in 1:nrow(MATR1)) {
for(j in 2:ncol(MATR1)) {
if (MATR1[i,j]%%2 == 0) {
MATR2[i,j] <- MATR1[i,j]/2
} else {MATR2[i,j] <- MATR1[i,j]}
}
}
return(matrix(MATR2, nrow(MATR1)))
But I can't get it to work. Can anyone see where I've made a mistake? Appreciate all help!
Use vectorized operations instead of for loops. You'll also need a function to determine whether numbers are prime. There are several possible algorithms, but none built into base R. I'll use numbers::isPrime here, though you can write your own prime sieve or other algorithm from scratch if you like.
First, some setup:
library(numbers)
set.seed(47) # for reproducibility
mat <- matrix(rpois(100, 10), 10) # sample matrix
mat
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
## [1,] 16 6 8 7 12 14 10 12 9 14
## [2,] 12 4 7 8 13 9 7 5 14 15
## [3,] 10 12 4 15 15 14 12 10 10 12
## [4,] 9 8 3 9 16 13 12 10 9 9
## [5,] 10 7 9 9 14 14 10 13 8 11
## [6,] 6 7 9 13 12 6 7 10 8 11
## [7,] 10 11 8 8 9 5 10 14 12 11
## [8,] 14 8 10 7 10 12 8 5 12 14
## [9,] 4 14 6 5 10 13 7 12 10 6
## [10,] 7 7 10 13 15 16 13 7 9 9
To define the function, assign to the subset that meets the criteria:
double_primes <- function(m){
m[isPrime(m)] <- m[isPrime(m)] * 2;
m
}
double_primes(mat)
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
## [1,] 16 6 8 14 12 14 10 12 9 14
## [2,] 12 4 14 8 26 9 14 10 14 15
## [3,] 10 12 4 15 15 14 12 10 10 12
## [4,] 9 8 6 9 16 26 12 10 9 9
## [5,] 10 14 9 9 14 14 10 26 8 22
## [6,] 6 14 9 26 12 6 14 10 8 22
## [7,] 10 22 8 8 9 10 10 14 12 22
## [8,] 14 8 10 14 10 12 8 10 12 14
## [9,] 4 14 6 10 10 26 14 12 10 6
## [10,] 14 14 10 26 15 16 26 14 9 9

Switching the first element with the last one in a loop

Is there a function in R which switches the first element with the last one in a vector? I have a for loop which need that reordering. From:
months = seq(1:12)
[1] 1 2 3 4 5 6 7 8 9 10 11 12
I would like to have:
[1] 12 1 2 3 4 5 6 7 8 9 10 11
and then again:
[1] 11 12 1 2 3 4 5 6 7 8 9 10
...
until the 12th position.
If you need a matrix output
cbind(c(months),embed(c(months, months), 12)[-13,-12])
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
# [1,] 1 12 11 10 9 8 7 6 5 4 3 2
# [2,] 2 1 12 11 10 9 8 7 6 5 4 3
# [3,] 3 2 1 12 11 10 9 8 7 6 5 4
# [4,] 4 3 2 1 12 11 10 9 8 7 6 5
# [5,] 5 4 3 2 1 12 11 10 9 8 7 6
# [6,] 6 5 4 3 2 1 12 11 10 9 8 7
# [7,] 7 6 5 4 3 2 1 12 11 10 9 8
# [8,] 8 7 6 5 4 3 2 1 12 11 10 9
# [9,] 9 8 7 6 5 4 3 2 1 12 11 10
#[10,] 10 9 8 7 6 5 4 3 2 1 12 11
#[11,] 11 10 9 8 7 6 5 4 3 2 1 12
#[12,] 12 11 10 9 8 7 6 5 4 3 2 1
Or another approached suggested by #Marat Talipov
z <- length(months)
i <- rep(seq(z),z) + rep(seq(z),each=z) - 1
matrix(months[ifelse(i>z,i-z,i)],ncol=z)
I'm afraid that you have to come up with a home-made function, something like this one:
rotate <- function(v,i=1) {
i <- i %% length(v)
if (i==0) return(v)
v[c(seq(i+1,length(v)),seq(i))]
}
Couple of examples:
v <- seq(12)
rotate(v,1)
# [1] 2 3 4 5 6 7 8 9 10 11 12 1
rotate(v,-1)
# [1] 12 1 2 3 4 5 6 7 8 9 10 11
You can also use tail and head functions:
x = c(tail(x,n), head(x,-n))
and modify n to rotate n times
The permute package can do this for you:
ap <- allPerms(length(months),
control = how(within = Within(type = "series"),
observed = TRUE))
ap[rev(seq_len(nrow(ap))), ]
(because of the way allPerms() does its work, we need to reverse the order of the rows, which is what the last line does.)
This gives:
> ap[rev(seq_len(nrow(ap))), ]
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
[1,] 1 2 3 4 5 6 7 8 9 10 11 12
[2,] 12 1 2 3 4 5 6 7 8 9 10 11
[3,] 11 12 1 2 3 4 5 6 7 8 9 10
[4,] 10 11 12 1 2 3 4 5 6 7 8 9
[5,] 9 10 11 12 1 2 3 4 5 6 7 8
[6,] 8 9 10 11 12 1 2 3 4 5 6 7
[7,] 7 8 9 10 11 12 1 2 3 4 5 6
[8,] 6 7 8 9 10 11 12 1 2 3 4 5
[9,] 5 6 7 8 9 10 11 12 1 2 3 4
[10,] 4 5 6 7 8 9 10 11 12 1 2 3
[11,] 3 4 5 6 7 8 9 10 11 12 1 2
[12,] 2 3 4 5 6 7 8 9 10 11 12 1
Technically this only works because months is the vector 1:12 and allPerms() returns a permutation matrix of the indices of the thing you want permuted. For different inputs, use ap to index into the thing you want to permute
perms <- ap
perms[] <- months[ap[rev(seq_len(nrow(ap))), ]]
perms

how to use a single vector to create a matrix with many columns

Is there a faster way to take a vector and turn it into a 10 columns matrix, like in the following output?
I have a vector of 9000 elements and I am trying to create 200 columns, from the most recent observations to its previous 200 observations, going backward for each columns.
In the example below, the number 10 represent the 10th obs in the vector, the 9 represents the 9th obs,..., the number 1 represents the first observation in the vector.
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 10 9 8 7 6 5 4 3 2 1
[2,] 11 10 9 8 7 6 5 4 3 2
[3,] 12 11 10 9 8 7 6 5 4 3
[4,] 13 12 11 10 9 8 7 6 5 4
[5,] 14 13 12 11 10 9 8 7 6 5
[6,] 15 14 13 12 11 10 9 8 7 6
[7,] 16 15 14 13 12 11 10 9 8 7
[8,] 17 16 15 14 13 12 11 10 9 8
[9,] 18 17 16 15 14 13 12 11 10 9
[10,] 19 18 17 16 15 14 13 12 11 10
[11,] 20 19 18 17 16 15 14 13 12 11
a<-1:20
z<-cbind(
a1<-a[-c(1:9)],
a2<-a[-c(1:8,length(a))],
a3<-a[-c(1:7,length(a)-1,length(a))],
a4<-a[-c(1:6,(length(a)-2):length(a))],
a5<-a[-c(1:5,(length(a)-3):length(a))],
a6<-a[-c(1:4,(length(a)-4):length(a))],
a7<-a[-c(1:3,(length(a)-5):length(a))],
a8<-a[-c(1:2,(length(a)-6):length(a))],
a9<-a[-c(1,(length(a)-7):length(a))],
a10<-a[-c((length(a)-8):length(a))]
)
z
I did the same thing for 40 columns, but I can't imagine doing the same thing for 200 columns.
Any help would be greatly appreciated. Thank you in advance
a<-1:100
z<-cbind(
a1<-a[-c(1:39)],
a2<-a[-c(1:38,length(a))],
a3<-a[-c(1:37,length(a)-1,length(a))],
a4<-a[-c(1:36,(length(a)-2):length(a))],
a5<-a[-c(1:35,(length(a)-3):length(a))],
a6<-a[-c(1:34,(length(a)-4):length(a))],
a7<-a[-c(1:33,(length(a)-5):length(a))],
a8<-a[-c(1:32,(length(a)-6):length(a))],
a9<-a[-c(1:31,(length(a)-7):length(a))],
a10<-a[-c(1:30,(length(a)-8):length(a))],
a11<-a[-c(1:29,(length(a)-9):length(a))],
a12<-a[-c(1:28,(length(a)-10):length(a))],
a13<-a[-c(1:27,(length(a)-11):length(a))],
a14<-a[-c(1:26,(length(a)-12):length(a))],
a15<-a[-c(1:25,(length(a)-13):length(a))],
a16<-a[-c(1:24,(length(a)-14):length(a))],
a17<-a[-c(1:23,(length(a)-15):length(a))],
a18<-a[-c(1:22,(length(a)-16):length(a))],
a19<-a[-c(1:21,(length(a)-17):length(a))],
a20<-a[-c(1:20,(length(a)-18):length(a))],
a21<-a[-c(1:19,(length(a)-19):length(a))],
a22<-a[-c(1:18,(length(a)-20):length(a))],
a23<-a[-c(1:17,(length(a)-21):length(a))],
a24<-a[-c(1:16,(length(a)-22):length(a))],
a25<-a[-c(1:15,(length(a)-23):length(a))],
a26<-a[-c(1:14,(length(a)-24):length(a))],
a27<-a[-c(1:13,(length(a)-25):length(a))],
a28<-a[-c(1:12,(length(a)-26):length(a))],
a29<-a[-c(1:11,(length(a)-27):length(a))],
a30<-a[-c(1:10,(length(a)-28):length(a))],
a31<-a[-c(1:9,(length(a)-29):length(a))],
a32<-a[-c(1:8,(length(a)-30):length(a))],
a33<-a[-c(1:7,(length(a)-31):length(a))],
a34<-a[-c(1:6,(length(a)-32):length(a))],
a35<-a[-c(1:5,(length(a)-33):length(a))],
a36<-a[-c(1:4,(length(a)-34):length(a))],
a37<-a[-c(1:3,(length(a)-35):length(a))],
a38<-a[-c(1:2,(length(a)-36):length(a))],
a39<-a[-c(1,(length(a)-37):length(a))],
a40<-a[-c((length(a)-38):length(a))]
)
z
Here's one possibility:
m <- matrix(nrow=11, ncol=10)
ncol(m) - col(m) + row(m)
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
# [1,] 10 9 8 7 6 5 4 3 2 1
# [2,] 11 10 9 8 7 6 5 4 3 2
# [3,] 12 11 10 9 8 7 6 5 4 3
# [4,] 13 12 11 10 9 8 7 6 5 4
# [5,] 14 13 12 11 10 9 8 7 6 5
# [6,] 15 14 13 12 11 10 9 8 7 6
# [7,] 16 15 14 13 12 11 10 9 8 7
# [8,] 17 16 15 14 13 12 11 10 9 8
# [9,] 18 17 16 15 14 13 12 11 10 9
# [10,] 19 18 17 16 15 14 13 12 11 10
# [11,] 20 19 18 17 16 15 14 13 12 11
I think embed() will be useful:
x <- 1:9000
m <- embed(x,200)
m <- m[,rev(seq(ncol(m)))] ## reverse columns

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