Related
I know that I can make a simple matrix (for example 1->20 numbers, 4,5 rows) using this:
x<- array(1:20, dim=c(4,5)); x
But I have no idea how to make a matrix similar to the one on the picture...
matrix(rep(1:4,4)^rep(0:3,each=4), byrow=TRUE, nrow=4)
[,1] [,2] [,3] [,4]
[1,] 1 1 1 1
[2,] 1 2 3 4
[3,] 1 4 9 16
[4,] 1 8 27 64
You can create a function if you want to be able to generate an analogous square matrix with an arbitrary number of rows.
power_mat = function(n) {
matrix(rep(1:n,n)^rep(1:n - 1, each=n), byrow=TRUE, nrow=n)
}
power_mat(6)
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 1 1 1 1 1
[2,] 1 2 3 4 5 6
[3,] 1 4 9 16 25 36
[4,] 1 8 27 64 125 216
[5,] 1 16 81 256 625 1296
[6,] 1 32 243 1024 3125 7776
Solution
t(sapply(0:3, function(x) (1:4)^x))
Result
[,1] [,2] [,3] [,4]
[1,] 1 1 1 1
[2,] 1 2 3 4
[3,] 1 4 9 16
[4,] 1 8 27 64
(You can easily verify this matches your matrix)
Explanation
Each row of the matrix is the vector c(1, 2, 3, 4) raised to the power of the row index (in a 0-based indexing system). So, we just use sapply() on the vector of powers to raise 1:4 to each power which will return a matrix. Because sapply() would return the results as column vectors, we use t() to transpose the result.
n <- 4
m <- 4
t(sapply( 0:(n-1), FUN = function (i){ return(c(1:m)**i) }))
where n is the number of rows, and m is the number of columns.
[,1] [,2] [,3] [,4]
[1,] 1 1 1 1
[2,] 1 2 3 4
[3,] 1 4 9 16
[4,] 1 8 27 64
n = 4
m = rbind(rep(1, n), t(replicate(n-1, 1:n)))
m ^ (row(m) - 1)
# [,1] [,2] [,3] [,4]
#[1,] 1 1 1 1
#[2,] 1 2 3 4
#[3,] 1 4 9 16
#[4,] 1 8 27 64
I want you to help me about R code.
I have an object, M(list & array). Like this.
object1 <- array(0, c(2,2,2))
M <- list(object1, object1)
Then, I want to reshape m(vector) into M structure.
m <- c(1:16)
When M is list & matrix object, I can use 'relist' function. However, I can't use it to array object. How can I reshape m into M structure??
We can specify the dims in array and use relist
lapply(relist(m, skeleton = M), array, dim(object1))
#[[1]]
#, , 1
# [,1] [,2]
#[1,] 1 3
#[2,] 2 4
#, , 2
# [,1] [,2]
#[1,] 5 7
#[2,] 6 8
#[[2]]
#, , 1
# [,1] [,2]
#[1,] 9 11
#[2,] 10 12
#, , 2
# [,1] [,2]
#[1,] 13 15
#[2,] 14 16
Or another option is
lapply(setNames(split(m, (seq_along(m)-1) %/% lengths(M)[1]), NULL), array, dim(object1))
#[[1]]
#, , 1
# [,1] [,2]
#[1,] 1 3
#[2,] 2 4
#, , 2
# [,1] [,2]
#[1,] 5 7
#[2,] 6 8
#[[2]]
#, , 1
# [,1] [,2]
#[1,] 9 11
#[2,] 10 12
#, , 2
# [,1] [,2]
#[1,] 13 15
#[2,] 14 16
NOTE: Both the solutions are one-line solutions
Here I have a
x <- array(1:20, dim=c(4,5))
x
[,1] [,2] [,3] [,4] [,5]
[1,] 1 5 9 13 17
[2,] 2 6 10 14 18
[3,] 3 7 11 15 19
[4,] 4 8 12 16 20
I also have a index array
i <- array(c(1:3,3:1), dim=c(3,2))
[,1] [,2]
[1,] 1 3
[2,] 2 2
[3,] 3 1
Then
x[i]
will extract X[1,3], X[2,2] and X[3,1]
However, what if I have
i <- array(c(1:3,3:1), dim=c(2,3))
The output is
x[i]
[1] 1 2 3 3 2 1
How can I understand this result?
For, example I if a had matrix like this:
realmatrix=matrix(1:16,ncol=4,nrow=4)
Which would give this:
[,1] [,2] [,3] [,4]
[1,] 1 5 9 13
[2,] 2 6 10 14
[3,] 3 7 11 15
[4,] 4 8 12 16
And I would like to make a function that would replace the two columns with a certain value ( for example 1:4) if it has a even number of colums, then the result should be something like this:
[,1] [,2] [,3] [,4]
[1,] 1 1 1 13
[2,] 2 2 2 14
[3,] 3 3 3 15
[4,] 4 4 4 16
And if the matrix has odd numbers of colums, the function should replace only the odd column, that is to say the central one:
This is the matrix with odd numbers of columns:
realmatrix2=matrix(1:12,ncol=3,nrow=4)
The final result:
[,1] [,2] [,3]
[1,] 1 1 9
[2,] 2 2 10
[3,] 3 3 11
[4,] 4 4 12
Thanks a lot!
Try:
fun2 <- function(mat, val){
stopifnot(length(val)==nrow(mat))
n <- ncol(mat)
if( (n/2) %%2 ==0){
mat[, c(n/2, n/2+1)] <- val
}
else {
mat[, ceiling(n/2)] <- val
}
mat
}
fun2(realmatrix, 1:4)
# [,1] [,2] [,3] [,4]
#[1,] 1 1 1 13
#[2,] 2 2 2 14
#[3,] 3 3 3 15
#[4,] 4 4 4 16
fun2(realmatrix2,1:4)
# [,1] [,2] [,3]
#[1,] 1 1 9
#[2,] 2 2 10
#[3,] 3 3 11
#[4,] 4 4 12
realmatrix5=matrix(1:32, ncol=8,nrow=4)
fun2(realmatrix5, 1:4)
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
#[1,] 1 5 9 1 1 21 25 29
#[2,] 2 6 10 2 2 22 26 30
#[3,] 3 7 11 3 3 23 27 31
#[4,] 4 8 12 4 4 24 28 32
Update
If you want to change the rows:
funR <- function(mat, val){
stopifnot(length(val)==ncol(mat))
n <- nrow(mat)
if((n/2) %%2==0){
mat[c(n/2, n/2+1),] <- rep(val, each=2)
}
else {
mat[ceiling(n/2),] <- val
}
mat
}
funR(realmatrix, 1:4)
# [,1] [,2] [,3] [,4]
#[1,] 1 5 9 13
#[2,] 1 2 3 4
#[3,] 1 2 3 4
#[4,] 4 8 12 16
realmatrix3 <- matrix(1:15, ncol=5)
funR(realmatrix3, 1:5)
# [,1] [,2] [,3] [,4] [,5]
#[1,] 1 4 7 10 13
#[2,] 1 2 3 4 5
#[3,] 3 6 9 12 15
I have a matrix in R like this:
|1|2|3|
|1|2|3|
|1|2|3|
Is there an easy way to rotate the entire matrix by 90 degrees clockwise to get these results?
|1|1|1|
|2|2|2|
|3|3|3|
and again rotating 90 degrees:
|3|2|1|
|3|2|1|
|3|2|1|
?
t does not rotate the entries, it flips along the diagonal:
x <- matrix(1:9, 3)
x
## [,1] [,2] [,3]
## [1,] 1 4 7
## [2,] 2 5 8
## [3,] 3 6 9
t(x)
## [,1] [,2] [,3]
## [1,] 1 2 3
## [2,] 4 5 6
## [3,] 7 8 9
90 degree clockwise rotation of R matrix:
You need to also reverse the columns prior to the transpose:
rotate <- function(x) t(apply(x, 2, rev))
rotate(x)
## [,1] [,2] [,3]
## [1,] 3 2 1
## [2,] 6 5 4
## [3,] 9 8 7
rotate(rotate(x))
## [,1] [,2] [,3]
## [1,] 9 6 3
## [2,] 8 5 2
## [3,] 7 4 1
rotate(rotate(rotate(x)))
## [,1] [,2] [,3]
## [1,] 7 8 9
## [2,] 4 5 6
## [3,] 1 2 3
rotate(rotate(rotate(rotate(x))))
## [,1] [,2] [,3]
## [1,] 1 4 7
## [2,] 2 5 8
## [3,] 3 6 9
90 degree counter clockwise rotation of R matrix:
Doing the transpose prior to the reverse is the same as rotate counter clockwise:
foo = matrix(1:9, 3)
foo
## [,1] [,2] [,3]
## [1,] 1 4 7
## [2,] 2 5 8
## [3,] 3 6 9
foo <- apply(t(foo),2,rev)
foo
## [,1] [,2] [,3]
## [1,] 7 8 9
## [2,] 4 5 6
## [3,] 1 2 3
m <- matrix(rep(1:3,each=3),3)
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 1 2 3
[3,] 1 2 3
t(m[nrow(m):1,])
[,1] [,2] [,3]
[1,] 1 1 1
[2,] 2 2 2
[3,] 3 3 3
m[nrow(m):1,ncol(m):1]
[,1] [,2] [,3]
[1,] 3 2 1
[2,] 3 2 1
[3,] 3 2 1
t(m)[ncol(m):1,]
[,1] [,2] [,3]
[1,] 3 3 3
[2,] 2 2 2
[3,] 1 1 1
An easy way to rotate a matrix by 180° is this:
m <- matrix(1:8,ncol=4)
# [,1] [,2] [,3] [,4]
# [1,] 1 3 5 7
# [2,] 2 4 6 8
rot <- function(x) "[<-"(x, , rev(x))
rot(m)
# [,1] [,2] [,3] [,4]
# [1,] 8 6 4 2
# [2,] 7 5 3 1
rot(rot(m))
# [,1] [,2] [,3] [,4]
# [1,] 1 3 5 7
# [2,] 2 4 6 8
R methods to rotate a matrix 90 degrees and -90 degrees
#first reverse, then transpose, it's the same as rotate 90 degrees
rotate_clockwise <- function(x) { t( apply(x, 2, rev))}
#first transpose, then reverse, it's the same as rotate -90 degrees:
rotate_counter_clockwise <- function(x) { apply( t(x),2, rev)}
#or if you want a library to help make things easier to read:
#install.packages("pracma")
library(pracma)
rotate_one_eighty <- function(x) { rot90(x, 2) }
rotate_two_seventy <- function(x) { rot90(x, -1) }
foo = matrix(1:9, 3)
foo
foo = rotate_clockwise(foo)
foo
foo = rotate_counter_clockwise(foo)
foo
foo = rotate_one_eighty(foo)
foo
Prints:
[,1] [,2] [,3]
[1,] 1 4 7 #original matrix
[2,] 2 5 8
[3,] 3 6 9
[,1] [,2] [,3]
[1,] 3 2 1
[2,] 6 5 4 #rotated 90 degrees
[3,] 9 8 7
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8 #rotated -90 degrees
[3,] 3 6 9
[,1] [,2] [,3]
[1,] 9 6 3
[2,] 8 5 2 #rotated 180 degrees
[3,] 7 4 1
Notice that rotating a matrix clockwise, then counterclockwise returns the numbers to their original position, then rotating by 180 is like rotating by 90 twice.
Or combined in a single function (based on Eric Leschinski):
rotate <- function(x, clockwise=T) {
if (clockwise) { t( apply(x, 2, rev))
} else {apply( t(x),2, rev)}
}