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
Related
The following bit of code should swap columns between levels of an array, but it results in a 'subscript out of bounds' error:
pop <- array(1:25, dim = c(5, 10, 2)) # 2-level array with 5 rows and 10 columns
m <- 0.20 # proportion of columns to swap
K <- 2
inds1 <- sample(ncol(pp), size = ceiling(ncol(x) * m), replace = FALSE) # sample random columns
inds2 <- sample(ncol(pop), size = ceiling(ncol(x) * m), replace = FALSE)
for (i in 1:K) { # swap columns between subarrays
for(j in 1:K) {
tmp <- pop[i,, inds1]
pop[i,, inds1] <- pop[j,, inds2]
pop[j,, inds2] <- tmp
}
}
Error in pop[i, , inds1] : subscript out of bounds
I wondering why R throws an error here. It should also work for any n-level array. Any idea what the issue might be?
I think the issue is that the way x is defined, the subsets are:
x[row, column, array level]
You are trying to access the columns in the array level spot. So if you had for example inds1 = 3 then pop[i, ,inds1] would be trying to access the third array which doesn't exist. See below for a working example. To address your current example we need more info on pop and K:
x <- array(1:25, dim = c(5, 10, 2)) # 2-level array with 5 rows and 10 columns
m <- 0.20 # proportion of columns to swap
set.seed(1)
inds1 <- sample(ncol(x), size = ceiling(ncol(x) * m), replace = FALSE) # sample random columns
inds2 <- sample(ncol(x), size = ceiling(ncol(x) * m), replace = FALSE)
x
#, , 1
#
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
#[1,] 1 6 11 16 21 1 6 11 16 21
#[2,] 2 7 12 17 22 2 7 12 17 22
#[3,] 3 8 13 18 23 3 8 13 18 23
#[4,] 4 9 14 19 24 4 9 14 19 24
#[5,] 5 10 15 20 25 5 10 15 20 25
#
#, , 2
#
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
#[1,] 1 6 11 16 21 1 6 11 16 21
#[2,] 2 7 12 17 22 2 7 12 17 22
#[3,] 3 8 13 18 23 3 8 13 18 23
#[4,] 4 9 14 19 24 4 9 14 19 24
#[5,] 5 10 15 20 25 5 10 15 20 25
inds1;inds2
[1] 3 4
[1] 6 9
So to swap column 3 & 6 and column 4 & 9 we can do:
temp <- x[, inds1, 1]
x[,inds1, 1] <- x[,inds2, 2]
x[,inds2, 2] <- temp
I'm trying to calculate the sum column wise of the cells in an 8x8 matrix M[[K]] for when the column is odd it adds the odd rows under it; if the column is even it add the even row cells under it. I then need this to loop through a data folder.
vin <- rep(c(1,0),(NoParticipants/2))
vout <- rep(c(0,1),(NoParticipants/2))
M <- vector("list")
total <- vector("list")
group <- vector("list")
for(k in 1:NoGames){
M[[k]] <- (CumulativeAdjacencyMatrices[[k]][[20]])
total[[k]] <- colSums(M[[k]])
group[[k]] <- (M[[k]]%*%vin)*vin + (NoRounds - (M[[k]]%*%vin))*vout
}
The line with group[[k]] is giving back negative integers (which it shouldn't). How can I re-write the command to do what I want it to? Any thoughts would be greatly appreciated :)
I found where I was wrong. I needed to replace NoRounds with total[[k]] in the last line.
I suggest an alternative to your approach as just traversing through odd and even indexes as follows :
#sample matrix
m <- matrix(sample.int(20, replace = TRUE), nrow = 8, ncol = 8)
> m
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,] 11 9 2 14 10 11 9 2
[2,] 17 6 9 7 4 17 6 9
[3,] 1 10 20 12 18 1 10 20
[4,] 1 14 8 3 12 1 14 8
[5,] 14 10 11 9 2 14 10 11
[6,] 7 4 17 6 9 7 4 17
[7,] 12 18 1 10 20 12 18 1
[8,] 3 12 1 14 8 3 12 1
#adding odd index columns
> colSums(m[,seq(1,ncol(m),2)])
[1] 66 69 83 83
#adding even index columns
> colSums(m[,seq(2,ncol(m),2)])
[1] 83 75 66 69
# column 1 = sum rows 1,3,5,7 and so on...
for(i in 1:(ncol(m)-2)){
m[,i] <- rowSums(m[,seq(i,8,2)])
}
Hope this helps.
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
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
Let's say t1 is :
t1 <- array(1:20, dim=c(10,10))
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 1 11 1 11 1 11 1 11 1 11
[2,] 2 12 2 12 2 12 2 12 2 12
[3,] 3 13 3 13 3 13 3 13 3 13
[4,] 4 14 4 14 4 14 4 14 4 14
[5,] 5 15 5 15 5 15 5 15 5 15
[6,] 6 16 6 16 6 16 6 16 6 16
[7,] 7 17 7 17 7 17 7 17 7 17
[8,] 8 18 8 18 8 18 8 18 8 18
[9,] 9 19 9 19 9 19 9 19 9 19
[10,] 10 20 10 20 10 20 10 20 10 20
I want to delete row 4-6 and column 7-9 from this matrix.
I know how to remove it one by one using
t2 <- t1[,-7]
t3 <- t2[,-8]
t4 <- t3[,-9]
t5 <- t4[-4,]
t6 <- t5[-5,]
t7 <- t6[-6,]
However, I believe it is the most stupid way of doing it. Could you mind to advice some smarter ways of doing it?
You can do:
t1<- t1[-4:-6,-7:-9]
You can use
t1<- t1[-4:-6,-7:-9]
or
t1 <- t1[-(4:6), -(7:9)]
or
t1 <- t1[-c(4, 5, 6), -c(7, 8, 9)]
You can pass vectors to select rows/columns to be deleted. First two methods are useful if you are trying to delete contiguous rows/columns. Third method is useful if You are trying to delete discrete rows/columns.
> t1 <- array(1:20, dim=c(10,10));
> t1[-c(1, 4, 6, 7, 9), -c(2, 3, 8, 9)]
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 2 12 2 12 2 12
[2,] 3 13 3 13 3 13
[3,] 5 15 5 15 5 15
[4,] 8 18 8 18 8 18
[5,] 10 20 10 20 10 20
You can also remove rows and columns by feeding a vector of logical boolean values to the matrix. This handles the situation where you have multiple non-contiguous rows or non-contiguous columns that need to be deleted.
# TRUE = Keep a row/column
# FALSE = Delete a row/column
#
# FALSE for rows 4, 5, and 6
# Row: 1 2 3 4 5 6 7 8 9 10
rows_to_keep <- c(TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE)
# FALSE for columns 7, 8, and 9
# Column: 1 2 3 4 5 6 7 8 9 10
cols_to_keep <- c(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE)
To remove just the rows:
t1 <- t1[rows_to_keep,]
To remove just the columns:
t1 <- t1[,cols_to_keep]
To remove both the rows and columns:
t1 <- t1[rows_to_keep, cols_to_keep]
This coding technique is useful if you don't know in advance what rows or columns you need to remove. The rows_to_keep and cols_to_keep vectors can be calculated as appropriate by your code.
> S = matrix(c(1,2,3,4,5,2,1,2,3,4,3,2,1,2,3,4,3,2,1,2,5,4,3,2,1),ncol = 5,byrow = TRUE);S
[,1] [,2] [,3] [,4] [,5]
[1,] 1 2 3 4 5
[2,] 2 1 2 3 4
[3,] 3 2 1 2 3
[4,] 4 3 2 1 2
[5,] 5 4 3 2 1
> S<-S[,-2]
> S
[,1] [,2] [,3] [,4]
[1,] 1 3 4 5
[2,] 2 2 3 4
[3,] 3 1 2 3
[4,] 4 2 1 2
[5,] 5 3 2 1
Just use the command S <- S[,-2] to remove the second column. Similarly to delete a row, for example, to delete the second row use S <- S[-2,].