In R, what does byrow do exactly? - r

I am new to R. I understand if for instance I have a matrix I am interested in building:
a <- matrix(c(1,2,3,4,5,6,7,8), nrow=2)
# [,1] [,2] [,3] [,4]
# [1,] 1 3 5 7
# [2,] 2 4 6 8
what exactly does byrow do differently in the example below? that is what I am having difficulty understanding
a <- matrix(c(1,2,3,4,5,6,7,8), nr=2, byrow = T)
# [,1] [,2] [,3] [,4]
# [1,] 1 2 3 4
# [2,] 5 6 7 8

Related

Transform 87x2 matrix into 29x6 in R

Suppose if I have a matrix with dimension 87x2. How can I convert into the dimension 29x6 in r
set.seed(1)
mat1 = matrix(runif(174), 87, 2)
I wanted to have like this below
> matrix(c(1:12), 6, 2)
[,1] [,2]
[1,] 1 7
[2,] 2 8
[3,] 3 9
[4,] 4 10
[5,] 5 11
[6,] 6 12
> matrix(c(1:12), 2, 6)
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 3 5 7 9 11
[2,] 2 4 6 8 10 12
Thank you in advance.
You can do the following:
mat1 <- matrix(c(1:12), 6, 2)
matrix(mat1, nrow = 2, ncol = 6)
# [,1] [,2] [,3] [,4] [,5] [,6]
#[1,] 1 3 5 7 9 11
#[2,] 2 4 6 8 10 12
Or set the dimensions directly using dim
dim(mat1) <- c(2, 6)

Sample from a matrix and split sampled and non sampled values in R

I want to sample 'n' rows from a matrix:
data <- matrix(data = 1:12, nrow = 4, ncol = 3)
[,1] [,2] [,3]
[1,] 1 5 9
[2,] 2 6 10
[3,] 3 7 11
[4,] 4 8 12
I use the following code :
selection <-sample(nrow(data),size = 2, replace = FALSE)
data[selection,]
[,1] [,2] [,3]
[1,] 4 8 12
[2,] 3 7 11
Is there a way I could return a matrix containing only the rows that haven't been sampled? In this case:
[,1] [,2] [,3]
[1,] 1 5 9
[2,] 2 6 10
Many thanks in advance.

Reducing a 3d array to 2d

Is there a more succinct, one-liner way to do the following?
x <- array(1:12, dim = c(3, 2, 2))
> x[1,,]
[,1] [,2]
[1,] 1 7
[2,] 4 10
> x[2,,]
[,1] [,2]
[1,] 2 8
[2,] 5 11
> x[3,,]
[,1] [,2]
[1,] 3 9
[2,] 6 12
# Reduce 3d array to 2d (Is there a more elegant way?)
y <- x
dim(y) <- c(nrow(y), 4)
> y
[,1] [,2] [,3] [,4]
[1,] 1 4 7 10
[2,] 2 5 8 11
[3,] 3 6 9 12
You can just feed your original array to the array constructor again, and use dim to get the dimension you want to preserve:
y <- array(x, dim = c(dim(x)[1], 4))
[,1] [,2] [,3] [,4]
[1,] 1 4 7 10
[2,] 2 5 8 11
[3,] 3 6 9 12
If you wanted a version that doesn't rely on hardcoding the number of columns:
y <- array(x, dim = c(dim(x)[1], dim(x)[2] * dim(x)[3]))

How to concatenate column repetitions of a matrix without a for loop

Let's say I have the below matrix:
[,1] [,2]
[1,] 1 2
[2,] 3 4
[3,] 5 6
I want to generate a matrix which is the concatenation (by column) of matrices that are generated by repetition of each column k times. For example, when k=3, below is what I want to get:
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 1 1 2 2 2
[2,] 3 3 3 4 4 4
[3,] 5 5 5 6 6 6
How can I do that without a for loop?
You can do this with column indexing. A convenient way to repeat each column number the correct number of times is the rep function:
mat[,rep(seq_len(ncol(mat)), each=3)]
# [,1] [,2] [,3] [,4] [,5] [,6]
# [1,] 1 1 1 2 2 2
# [2,] 3 3 3 4 4 4
# [3,] 5 5 5 6 6 6
In the above expression, seq_len(ncol(mat)) is the sequence from 1 through the number of columns in the matrix (you could think of it like 1:ncol(mat), except it deals nicely with some special cases like 0-column matrices).
Data:
(mat <- matrix(1:6, nrow=3, byrow = TRUE))
# [,1] [,2]
# [1,] 1 2
# [2,] 3 4
# [3,] 5 6
We can repeat each element of matrix k times and fit the vector in a matrix where number of columns is k times the original one.
k <- 3
matrix(rep(t(mat), each = k), ncol = ncol(mat) * k, byrow = TRUE)
# [,1] [,2] [,3] [,4] [,5] [,6]
#[1,] 1 1 1 2 2 2
#[2,] 3 3 3 4 4 4
#[3,] 5 5 5 6 6 6

how to combine two lists with the same structure in r

I have two lists,
say
list1<-list(a=c(0,1,2),b=c(3,4,5));
list2<-list(a=c(7,8,9),b=c(10,11,12));
how to get a combined list as
list(a= rbind(c(0,1,2),c(7,8,9)), b = rbind(c(3,4,5),c(10,11,12)) )
I can do it by for loops. Any other simpler way for this?
Thanks!
I think this would work in general:
l<-lapply(names(list1),function(x) rbind(list1[[x]],list2[[x]]))
names(l)<-names(list1)
But if you could guarantee the same order in each list, this would work
mapply(rbind,list1,list2,SIMPLIFY=FALSE)
# $a
# [,1] [,2] [,3]
# [1,] 0 1 2
# [2,] 7 8 9
#
# $b
# [,1] [,2] [,3]
# [1,] 3 4 5
# [2,] 10 11 12
Using sapply with simplify=FALSE gets you the elements named for free:
> sapply(names(list1),function(n){rbind(list1[[n]],list2[[n]])},simplify=FALSE)
$a
[,1] [,2] [,3]
[1,] 0 1 2
[2,] 7 8 9
$b
[,1] [,2] [,3]
[1,] 3 4 5
[2,] 10 11 12

Resources