I want to create x randomised matrices where only the columns are permuted but the rows are kept constant. I already took a look at permatful() in the vegan package. Nevertheless, i was not able to generate the desired result even though i am quite sure that this should be possible somehow.
df = matrix(c(2,3,1,4,5,1,3,6,2,4,1,3), ncol=3)
This is (one possible) desired result
[,1] [,2] [,3]
[1,] 2 5 2
[2,] 3 1 4
[3,] 1 3 1
[4,] 4 6 3
v
v permutation
v
[,1] [,2] [,3]
[1,] 5 2 2
[2,] 1 4 3
[3,] 3 1 1
[4,] 6 3 4
I tried something like permatfull(df, times=1, fixedmar = "rows", shuffle = "samp") which results in
[,1] [,2] [,3]
[1,] 5 2 2
[2,] 1 4 3
[3,] 3 1 1
[4,] 3 4 6
Now column 1 (originally column 2) has changed from 5,1,3,6 to 5,1,3,3.
Anyone an idea why I do not get the expected result?
Thanks in Advance,
Christian
Related
Using R, I am trying to extract unique rows in a matrix, where a "unique row" is subject to all the values in a given row.
For example if I had this data set:
x = matrix(c(1,1,1,2,2,5,1,2,2,1,2,1,5,3,5,2,1,1),6,3)
Rows 1 & 6, and rows 4 & 5 are duplicated since (1,1,5) = (5,1,1) and (2,1,2) = (2,2,1).
Ultimately, i'm trying to end up with something in the form of:
y = matrix(c(1,1,1,2,1,2,2,1,5,3,5,2),4,3)
or
z = matrix(c(1,1,2,5,2,2,2,1,3,5,1,1),4,3)
The order doesn't matter as long as only one of the unique rows remains. I've searched online, but functions such as unique() and duplicated() have only worked for exact matching rows.
Thanks in advance for any help you provide.
Another answer: use sets. Slightly modified matrix:
library(sets)
x <- matrix(c(1,1,1,2,2,5,5, 1,2,2,1,2,1,5, 5,3,5,2,1,1,1),7,3)
x
[,1] [,2] [,3]
[1,] 1 1 5
[2,] 1 2 3
[3,] 1 2 5
[4,] 2 1 2
[5,] 2 2 1
[6,] 5 1 1
[7,] 5 5 1
If (5,1,1) = (5,5,1) you can use just ordinary sets:
a <- sapply(1:nrow(x), function(i) as.set(x[i,]))
x[!duplicated(a),]
[,1] [,2] [,3]
[1,] 1 1 5
[2,] 1 2 3
[3,] 1 2 5
[4,] 2 1 2
Note: rows 6 and 7 are both gone.
If (5,1,1) != (5,5,1), use generalized sets:
b <- sapply(1:nrow(x), function(i) as.gset(x[i,]))
x[!duplicated(b),]
[,1] [,2] [,3]
[1,] 1 1 5
[2,] 1 2 3
[3,] 1 2 5
[4,] 2 1 2
[5,] 5 5 1
I am trying to convert the rows of the matrices below into indices to subset from another matrix. The first matrix would generate four indices to be used for subsetting from a matrix called data, shown at the bottom. The second matrix would generate six indices, each of length two, and so on.
library(gtools) # library for combinations()
matrix(match(combinations(n=4,r=1,v=LETTERS[1:4]),LETTERS),ncol=1)
[,1]
[1,] 1
[2,] 2
[3,] 3
[4,] 4
matrix(match(combinations(n=4,r=2,v=LETTERS[1:4]),LETTERS),ncol=2)
[,1] [,2]
[1,] 1 2
[2,] 1 3
[3,] 1 4
[4,] 2 3
[5,] 2 4
[6,] 3 4
matrix(match(combinations(n=4,r=3,v=LETTERS[1:4]),LETTERS),ncol=3)
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 1 2 4
[3,] 1 3 4
[4,] 2 3 4
matrix(match(combinations(n=4,r=4,v=LETTERS[1:4]),LETTERS),ncol=4)
[,1] [,2] [,3] [,4]
[1,] 1 2 3 4
data <- matrix(rnorm(16,0),ncol=4)
data[,1]
data[,2]
data[,3]
data[,4]
The second matrix would generate indices to be used like:
data[,c(1,2)]
data[,c(1,3)]
data[,c(1,4)]
data[,c(2,3)]
etc.
What would a generic, vectorized function look like to accomplish the above for varying n?
Can matrix row and column names be set to defaults (e.g., [1,], [2,]... [,1], [,2]...) in R?
For example, is there a quick way to transform a matrix like this
x1 <- matrix(1:9,nrow=3,ncol=3,dimnames=list(1:3,letters[1:3]))
> x1
a b c
1 1 4 7
2 2 5 8
3 3 6 9
into this
> x1
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
You're looking for dimnames<-:
dimnames(x1) <- NULL
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
You can see the help file by typing ?dimnames. It is also linked from ?matrix.
I am trying to calculate the cumulative product of a matrix, I will present my example below.
sample <- matrix(c(1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5),6,5,byrow=T)
sample
[,1] [,2] [,3] [,4] [,5]
[1,] 1 2 3 4 5
[2,] 1 2 3 4 5
[3,] 1 2 3 4 5
[4,] 1 2 3 4 5
[5,] 1 2 3 4 5
[6,] 1 2 3 4 5
I would like to compute the cumulative product for each row across each column. So the result should looks like:
[,1] [,2] [,3] [,4] [,5]
[1,] 1 2 6 24 120
[2,] 1 2 6 24 120
[3,] 1 2 6 24 120
[4,] 1 2 6 24 120
[5,] 1 2 6 24 120
[6,] 1 2 6 24 120
I have tried cumprod(sample) and apparently it does not work well with matrix in this way, I am wondering if there is any shortcut to do this without using a loop.
Thank you very much for your help!
sample <- matrix(rep(1:5,6),ncol=5,byrow=TRUE)
(it may not be wise to use sample as a variable name, since it's also the name of a built-in function; it is wise to spell out TRUE rather than using the T shortcut)
This does it:
t(apply(sample,1,cumprod))
apply(...,1,cumprod) applies the cumprod function to each row ("2" would apply it to columns). Because of the way that apply arranges its results:
If each call to ‘FUN’ returns a vector of length ‘n’, then ‘apply’ returns an array of dimension ‘c(n, dim(X)[MARGIN])’ if ‘n > 1’.
you have to transpose (t()) the results.
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