How to add to a list of matrices in R? - r

Given a dataset 'train' that has 1607 rows and 256 columns, I want to make each row (with 256 elements each) a 16x16 matrix and have a list to hold 1607 of such matrices. All observations in the train data are values between -1 and 1. For example, a row vector in the train could be
a <- seq(from = -1, to = 1, length = 256)
When I try to run a loop like this,
x <- lapply(1:nrow(train), matrix, data=0, nrow=16, ncol=16) #creates list of 1607 matrices of 0's
for (i in length(x)) {
x[[i]] <- matrix(X_train[i,], nrow=16, ncol=16) #replace each element (matrix) of list x with a matrix of the same dimension from train
}
I keep getting the same unmodified list x with matrices of 0 for all elements of x. What am I doing wrong?

for (i in length(x)) {
Here, you are looping over one value, namely, length(x). You probably want to loop over all values from 1 to the length of x. You do this with
for (i in 1:length(x)) {
or
for (i in seq_along(x)) {
The latter has the benefit that it won't produce a bad result if x is empty. But really, you don't need to make a loop at all, or produce a list of blank matrices which you immediately discard. Instead, do:
rows <- seq_len(nrow(X_train))
x <- lapply(rows, function(row) matrix(X_train[row, ], nrow=16, ncol=16))

Related

For loop to create list of vectors of varying length

For loop to create list of vectors of varying length.
I created this dataframe
set.seed = 1
x <- 1:10
y <- rnorm(10)
z <- rexp(10)
w <- sample(1:100, 10)
tb <- tibble(x,y,z,w)
I would like to create a list containing the ranges of the variables in the table.
This is what I tried.
L <- length(names(tb))
names <- vector("list",L)
for (i in 1:L){
names[i] <- range(tb[i])
}
I created a list of length 4, I tried to use the for loop above to get the ranges, However it only takes the minimum of each range and gives this error
Warning message:
In names[1] <- x :
number of items to replace is not a multiple of replacement length
I believe I need to pre allocate a list of vectors, all of which are length 2 inside the list, but I can't figure out how to do that.

double for-loop to calculate the mean in a range of rows in a matrix

dataset <- matrix(rnorm(100), 20, 5)
My dataset is a matrix of 100 returns, of 5 assets over 20 days.
I want to caluclate the average return for each asset, between 1:10 rows and 11:20 rows.
Then, I want to include the returns so computed in two vectors, in turn, included in a list.
The following list should include the two vectors of returns computed between rows 1:10 and 11:20.
returns <- vector(mode="list", 2)
I have implemented a for-loop, as reported below, to calculate the mean of returns only between 1:10.
assets <- 5
r <- rep(0, assets) # this vector should include the returns over 1:10
for(i in 1:assets){
r[i] <- mean(data[1:10,i])
}
returns[[1]] <- r
How could I manage this for-loop in order to calculate also the mean of returns between 11:20 rows?
I have tried to "index" the rows of the dataset, in the following way.
time <- c(1, 10, 11, 20)
and then implement a double for-loop, but the length are different. Moreover, in this case, I meet difficulties in managing the vector "r". Because, in this case, I should have two vectors and no longer only one as before.
for(j 1:length(time){
for(i in 1:assets){
r[i] <- mean(data[1:10,i])
}}
returns[[1]] <- r
You don't even need a for loop. You can use colMeans
returns <- vector(mode="list", 2)
returns[[1]] <- colMeans(dataset[1:10,])
returns[[2]] <- colMeans(dataset[11:20,])
Using a for loop, your solution could be something like the following
for(i in 1:assets){
returns[[1]] <- c(returns[[1]], mean(dataset[1:10,i]))
returns[[2]] <- c(returns[[2]], mean(dataset[11:20,i]))
}

R How do I convert a file organised in rows into a set of matrices-one for each row

I have 2 files that have corresponding X and Y values each contain the values in rows and there are 100 rows and 50 values in each. I at first used a read.table command to read each file into a variable, "X and Y". Now I have to make each row into it's own matrix (with one column) and then bind them so that the 50 Xs and 50 Ys will line up i.e. the matrix made from the first row of X values will line up with that of the first row in the Y coordinates.
After transposing the X and Y so that the rows would become columns ( I thought that would be easier) I tried converting them to matrices in a for loop with:
for(i in 1:49){
x<-as.matrix(trajx[,i])#specifying i in columns-variable was transposed
x<-cbind(x, as.matrix(trajy[,i]))
}
However this only returns two 50-long columns and the values seem totally randomly selected from the X and Y datasets.
You may want first transform the data frames into matrices, and then pick rows, not columns:
X <- as.matrix(X) # improves efficiency
Y <- as.matrix(Y)
for(i in 1:50) {
x <- cbind(X[i,], Y[i,]) # note: firs index picks rows
# note: this x will be be overwritten during the next loop
}
(untested) If you want to save all 50 matrices, you may want to add lines x <- vector("list", 50) before the loop, and x[[i]] <- ... instead of x <- ... in the loop.

Creating multiple matrices with a for loop

I would like to create ncol(y) number of matrices taking each column from y matrix and replicating it rep number of times. I am not doing the for loop right though. To reiterate, below I would like to get three separate matrices, the first one would have values of 1 to 100 repeated 200 times (they come from the first columns of y), second would have vector 101-200 repeated 200 times (2nd column of y) as well and the third one would have values 201-300 repeated 200 times (3rd column of y). Preferably the output name would be matrix1, matrix2 or a list.
y <- matrix(1:300,100,3)
rep = 200
for (i in 1:ncol(y)) {
newmatrix <- replicate(rep,y[,i])
valuematrix[[i]] <- newmatrix
}
You're missing the initialization of valuematrix. You can do this through
valuematrix <- list()
just before the for loop.
You might also consider using lapply to solve this problem. It automatically stores the matrices in a list.
y <- matrix(1:300, 100, 3)
rep = 200
matList <- lapply(1:ncol(y), function(i) replicate(rep, y[,i]))

Creating a matrix from operations done on another dataset

I have a large dataset, X with 58140 columns, filled with either 1 or 0
I would like to create a 58139 x 58139 matrix from the information of the 58139 columns in the dataset.
For each Aij in the matrix I would like to find the number of common rows which contain the value 1 for Column i+1 and Column J+1 from X.
I figured I can do this through sum(X[[2]]+X[[3]] == 2) for the A12 element of the matrix.
The only problem left is a way to code the matrix in.
You can use mapply. That returns a numeric vector. Then you can just wrap it in a call to matrix and ignore the first row and column.
# sample data
set.seed(123)
X <- data.frame(matrix(rbinom(200, 1, .5), nrow=10))
#
A <- matrix(mapply(function(i, j) sum(rowSums(X[, c(i,j)])==2),
i=rep(1:ncol(X), ncol(X)),
j=rep(1:ncol(X), each=ncol(X))),
ncol=ncol(X))[-1, -1]
A

Resources