How can I shuffle the values of matrix m1 across each column:
Initial:
m1=cbind(c(1,2,3),c(4,5,6),c(7,8,9))
Do something and:
m1=cbind(c(7,5,3),c(4,2,9),c(1,8,6))
Thanks
You can call the sample function on each column of your matrix to shuffle it:
set.seed(100)
apply(m1, 2, sample)
# [,1] [,2] [,3]
# [1,] 1 5 8
# [2,] 3 4 9
# [3,] 2 6 7
ehm, you mean by row in your example?!
shuffle a list:
# create a list from 1 to 9
x <- seq(1,9)
# shuffle
x[order(runif(length(x)))]
shuffle rows/columns of a matrix:
# example matrix
m1 <- matrix(x,ncol=3)
# shuffle by row
for (i in 1:nrow(m1)) m1[i,] <- m1[i,order(runif(length(m1[i,])))]
# shuffle by col
for (i in 1:ncol(m1)) m1[,i] <- m1[order(runif(length(m1[i,]))),i]
edit: maybe sample is better... http://stat.ethz.ch/R-manual/R-devel/library/base/html/sample.html
You can also put sample in matrix indices and sample the rows and columns.
To shuffle the entire matrix,
> m1[sample(nrow(m1)), sample(ncol(m1))]
# [,1] [,2] [,3]
#[1,] 6 9 3
#[2,] 5 8 2
#[3,] 4 7 1
Or by row
> m1[sample(nrow(m1)), ]
# [,1] [,2] [,3]
#[1,] 3 6 9
#[2,] 1 4 7
#[3,] 2 5 8
Or by column
> m1[,sample(ncol(m1))]
# [,1] [,2] [,3]
#[1,] 7 4 1
#[2,] 8 5 2
#[3,] 9 6 3
Related
I have a small matrix, say
x <- matrix(1:10, nrow = 5) # values 1:10 across 5 rows and 2 columns
The result is
[,1] [,2]
[1,] 1 6
[2,] 2 7
[3,] 3 8
[4,] 4 9
[5,] 5 10
What I want to be able to do now is duplicate random rows in x; for example, producing
[,1] [,2]
[1,] 1 6
[2,] 2 7
[3,] 5 10
[4,] 4 9
[5,] 5 10
I believe the R function 'rep()' is the solution and also 'sample()', but I don't want to have to specify the size argument in sample(); i.e., I want an arbitrary number of rows to be duplicated each time.
Is there a simple way of accomplishing this using rep() and sample()?
We can use the sample function. I've used set.seed for reproducibility, if you remove that line the results should change.
set.seed(1848) # reproducibility
x[sample(x = nrow(x), size = nrow(x), replace = T), ]
[,1] [,2]
[1,] 1 6
[2,] 2 7
[3,] 5 10
[4,] 1 6
[5,] 5 10
Another option could be as sample a row number and replace that with another sampled row number. It will be as:
x[sample(1:nrow(x),1),] <- x[sample(1:nrow(x),1),]
x
# [,1] [,2]
#[1,] 5 10
#[2,] 2 7
#[3,] 3 8
#[4,] 4 9
#[5,] 5 10
OR
Just to duplicate upto 3 random rows, solution could be:
x[sample(1:nrow(x),3),] <- x[sample(1:nrow(x),3),]
I have two matrices that i want to sum
mat1<-matrix(1:4,2,2)
mat2<-matrix(5:8,2,2)
mat1
[,1] [,2]
[1,] 1 3
[2,] 2 4
mat2
[,1] [,2]
[1,] 5 7
[2,] 6 8
what i want is this
mat_sum
[,1] [,2]
[1,] 6 10
[2,] 8 12
I tried
mat_sum <- sapply(seq_along(mat1), function(i)
mat1[[i]]+mat2[[i]])
but then it doesnt return a matrix
[1] 6 8 10 12
How can i get it to return a matrix?
We can do a regular + which will preserve the matrix format and does the elementwise summation
mat1 + mat2
# [,1] [,2]
#[1,] 6 10
#[2,] 8 12
If there are many matrices, place it in a list and use Reduce with +
Reduce(`+`, mget(paste0("mat", 1:2)))
First create a "row" vector and a "column" vector in R:
> row.vector <- seq(from = 1, length = 4, by = 1)
> col.vector <- {t(seq(from = 1, length = 3, by = 2))}
From that I'd like to create a matrix by, e.g., multiplying each value in the row vector with each value in the column vector, thus creating from just those two vectors:
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 6 10
[3,] 3 9 15
[4,] 4 12 20
Can this be done with somehow using apply()? sweep()? ...a for loop?
Thank you for any help!
Simple matrix multiplication will work just fine
row.vector %*% col.vector
# [,1] [,2] [,3]
# [1,] 1 3 5
# [2,] 2 6 10
# [3,] 3 9 15
# [4,] 4 12 20
You'd be better off working with two actual vectors, instead of a vector and a matrix:
outer(row.vector,as.vector(col.vector))
# [,1] [,2] [,3]
#[1,] 1 3 5
#[2,] 2 6 10
#[3,] 3 9 15
#[4,] 4 12 20
Here's a way to get there with apply. Is there a reason why you're not using matrix?
> apply(col.vector, 2, function(x) row.vector * x)
## [,1] [,2] [,3]
## [1,] 1 3 5
## [2,] 2 6 10
## [3,] 3 9 15
## [4,] 4 12 20
I am trying to determine which columns were sampled from a matrix randomly sampled within each row. The function sample does not appear to have the ability to tell you which locations were actually sampled. Now, a simple matching routine can solve the problem if all values are unique. However, they are not in my case, so this will not work.
x <- c(2,3,5,1,6,7,2,3,5,6,3,5)
y <- matrix(x,ncol=4,nrow=3)
random <- t(apply(y,1,sample,2,replace=FALSE))
y
[,1] [,2] [,3] [,4]
[1,] 2 1 2 6
[2,] 3 6 3 3
[3,] 5 7 5 5
random
[,1] [,2]
[1,] 2 6
[2,] 3 3
[3,] 5 5
With repeated values in the original matrix, I cannot tell if random[1,1] was sampled from column 1 or column 3, since they both have a value of 2. Hence, matching won't work here.
Accompanying the matrix "random" I would also like a matrix that gives the column from which each value was sampled, in an identically sized matrix. For example, such as:
[,1] [,2]
[1,] 1 4
[2,] 1 3
[3,] 3 4
Thanks!
You need to save your random selections from sample separately so you don't have to worry about matching later. E.g., using y again:
y
# [,1] [,2] [,3] [,4]
#[1,] 2 1 2 6
#[2,] 3 6 3 3
#[3,] 5 7 5 5
set.seed(42)
randkey <- t(replicate(nrow(y),sample(1:ncol(y),2)))
# [,1] [,2]
#[1,] 4 3
#[2,] 2 3
#[3,] 3 2
random <- matrix(y[cbind(c(row(randkey)), c(randkey))], nrow(y))
# [,1] [,2]
#[1,] 6 2
#[2,] 6 3
#[3,] 5 7
In R, let M be the matrix
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 1 3 3
[3,] 2 4 5
[4,] 6 7 8
I would like to select the submatrix m
[,1] [,2] [,3]
[1,] 1 3 3
[2,] 2 4 5
[3,] 6 7 8
using unique on M[,1], specifying to keep the row with the maximal value in the second columnM.
At the end, the algorithm should keep row [2,] from the set \{[1,], [2,]\}. Unfortunately unique() returns me a vector with actual values, and not row numbers, after elimination of duplicates.
Is there a way to get the asnwer without the package plyr?
Thanks a lot,
Avitus
Here's how:
is.first.max <- function(x) seq_along(x) == which.max(x)
M[as.logical(ave(M[, 2], M[, 1], FUN = is.first.max)), ]
# [,1] [,2] [,3]
# [1,] 1 3 3
# [2,] 2 4 5
# [3,] 6 7 8
You're looking for duplicated.
m <- as.matrix(read.table(text="1 2 3
1 3 3
2 4 5
6 7 8"))
m <- m[order(m[,2], decreasing=TRUE), ]
m[!duplicated(m[,1]),]
# V1 V2 V3
# [1,] 6 7 8
# [2,] 2 4 5
# [3,] 1 3 3
Not the most efficient:
M <- matrix(c(1,1,2,6,2,3,4,7,3,3,5,8),4)
t(sapply(unique(M[,1]),function(i) {temp <- M[M[,1]==i,,drop=FALSE]
temp[which.max(temp[,2]),]
}))
# [,1] [,2] [,3]
#[1,] 1 3 3
#[2,] 2 4 5
#[3,] 6 7 8