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
Related
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
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
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
Imagine we have one matrix of 5*5 (25 elements)
m<-matrix(1:25,5,5)
> m
[,1] [,2] [,3] [,4] [,5]
[1,] 1 6 11 16 21
[2,] 2 7 12 17 22
[3,] 3 8 13 18 23
[4,] 4 9 14 19 24
[5,] 5 10 15 20 25
I want to produce large matrix with different dimensions from the matrix “m”
For example 5*8, now my second column of new matrix must have overlap with the first one and so on.
So bigger dimension (e.g 5*8) matrix would be like : (it is just example and not sure the amount of shift is correct)
[,1] [,2] [,3] [,4] ……………………[,8]
[1,] 1 4 7 10 …………………… 19
[2,] 2 5 8 11 …………………… 20
[3,] 3 6 9 12 …………………… 21
[4,] 4 7 10 13 …………………… 22
[5,] 5 8 11 14 …………………… 23
In fact in each column we have a shift back to some elements of last column in order to prevent from reaching the last element of original matrix and producing NA value.
Please anyone knows how to create such a larger matrix?
The hardest part for me is to calculate the amount of SHIFT value regarding to the size of larger matrix. The larger matrix must cover almost all elements of the original one. (it is ok to miss some last elements)
thanks
I'm not sure what you want, but this might be helpful.
rows <- 5
cols <- 8
overlap <- 1
matrix(rep(seq(1,cols)*(rows-overlap),each=rows)+seq(1,rows)-(rows-overlap),nrow=rows)
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,] 1 5 9 13 17 21 25 29
[2,] 2 6 10 14 18 22 26 30
[3,] 3 7 11 15 19 23 27 31
[4,] 4 8 12 16 20 24 28 32
[5,] 5 9 13 17 21 25 29 33
overlap <- 2
matrix(rep(seq(1,cols)*(rows-overlap),each=rows)+seq(1,rows)-(rows-overlap),nrow=rows)
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,] 1 4 7 10 13 16 19 22
[2,] 2 5 8 11 14 17 20 23
[3,] 3 6 9 12 15 18 21 24
[4,] 4 7 10 13 16 19 22 25
[5,] 5 8 11 14 17 20 23 26
overlap <- 3
matrix(rep(seq(1,cols)*(rows-overlap),each=rows)+seq(1,rows)-(rows-overlap),nrow=rows)
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,] 1 3 5 7 9 11 13 15
[2,] 2 4 6 8 10 12 14 16
[3,] 3 5 7 9 11 13 15 17
[4,] 4 6 8 10 12 14 16 18
[5,] 5 7 9 11 13 15 17 19
the maximum efficiency of coverage is: (the best value of overlap)
> overlap<-ceiling(rows*(1-length(dna1)/(cols*rows)))+round(rows/cols)
I have this code in R:
seq1 <- seq(1:20)
mat <- matrix(seq1, 2)
and the result is:
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 1 3 5 7 9 11 13 15 17 19
[2,] 2 4 6 8 10 12 14 16 18 20
Does R have an option to suppress the display of column names and row names so that I don't get the [,1] [,2] and so on?
If you want to retain the dimension names but just not print them, you can define a new print function.
print.matrix <- function(m){
write.table(format(m, justify="right"),
row.names=F, col.names=F, quote=F)
}
> print(mat)
1 3 5 7 9 11 13 15 17 19
2 4 6 8 10 12 14 16 18 20
This works for matrices:
seq1 <- seq(1:20)
mat <- matrix(seq1, 2)
dimnames(mat) <-list(rep("", dim(mat)[1]), rep("", dim(mat)[2]))
mat
There is, also, ?prmatrix:
prmatrix(mat, collab = rep_len("", ncol(mat)), rowlab = rep_len("", ncol(mat)))
#
# 1 3 5 7 9 11 13 15 17 19
# 2 4 6 8 10 12 14 16 18 20
Solution by Fojtasek is probably the best, but here is another using sprintf instead.
print.matrix <- function(x,digits=getOption('digits')){
fmt <- sprintf("%% .%if",digits)
for(r in 1:nrow(x))
writeLines(paste(sapply(x[r,],function(x){sprintf(fmt,x)}),collapse=" "))
}
> writeLines(apply(format(matrix(1:20,2)),1,paste,collapse=" "))
1 3 5 7 9 11 13 15 17 19
2 4 6 8 10 12 14 16 18 20
> writeLines(apply(matrix(1:20,2),1,paste,collapse=" "))
1 3 5 7 9 11 13 15 17 19
2 4 6 8 10 12 14 16 18 20