Creating multiple matrices with a for loop - r

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]))

Related

How to add to a list of matrices in 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))

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]))
}

for loop only showing result of one case in R

I intend to fill a matrix I created that has 1000 rows and 2 columns. Here B is 1000.
resampled_ests <- matrix(NA, nrow = B, ncol = 2)
names(resampled_ests) <- c("Intercept_Est", "Slope_Est")
I want to fill it using a for loop looping from 1 to 1000.
ds <- diamonds[resampled_values[b,],]
Here, each of the ds(there should be 1000 versions of it in the for loop) is a data frame with 2 columns and 2000 rows. and I would like to use the lm() function to get the Beta coefficients of the two columns of data.
for (b in 1:B) {
#Write code that fills in the matrix resample_ests with coefficent estimates.
ds <- diamonds[resampled_values[b,],]
lm2 <- lm(ds$price~ds$carat, data = ds)
rowx <- coefficients(lm2)
resampled_ests <- rbind(rowx)
}
However, after I run the loop, resampled_ests, which is supposed to be a matrix of 1000 rows only shows 1 row, 1 pair of coefficients. But when I test the code outside of the loop by replacing b with numbers, I get different results which are correct. But by putting them together in a for loop, I don't seem to be row binding all of these different pairs of coefficients. Can someone explain why the result matrix resampled_etsis only showing one result case(1 row) of data?
rbind(x) returns x because you're not binding it to anything. If you want to build a matrix row by row, you need something like
resampled_ests <- rbind(resampled_ests, rowx)
This also means you need to initialize resampled_ests before the loop.
Which, if you're doing that anyway, I might just make a 1000 x 2 matrix of zeros and fill in the rows in the loop. Something like...
resampled_ests <- matrix(rep(0, 2*B), nrow=B)
for (b in 1:B) {
ds <- diamonds[resampled_values[b,],]
lm2 <- lm(ds$price~ds$carat, data = ds)
rowx <- coefficients(lm2)
resampled_ests[b,] <- rowx
}

why nrow(dataframe) and length(dataframe) in r give different results?

I have a ordered data frame and want to know the number of the last row.
data_ranking <- reduced_data[order(reduced_data$outcome,reduced_data$hospital,na.last=NA),]
nobs <- nrow(data_ranking)
gives me different results of
data_ranking <- reduced_data[order(reduced_data$outcome,reduced_data$hospital,na.last=NA),]
nobs <- length(data_ranking)
I would like to understand why is that. It seems that nrowgives me the answer I'm looking for, but I don't understand why.
data frames are essentially lists where each element has the same length.
Each element of the list is a column, hence length gives you the length of the list, usually the number of columns.
nrow will give you the number of rows, ncol (or length) the number of columns.
The obvious equivalence of columns and list lengths gets messy once we have nonstandard structures within the data.frame (eg. matrices) and
x <- data.frame(y=1:5, z = matrix(1:10,ncol=2))
ncol(x)
# 3
length(x)
# 3
x1 <- data.frame(y=1:5, z = I(matrix(1:10,ncol=2)))
ncol(x1)
# 2
length(x)
# 2

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.

Resources