Optimizing an R code with For Loop with matrix - r

I need to convert the following code to one with for loop, what is the easiest way to do it?
set.seed(123)
iter <- 1000
s1 <- 2
mat1 <- matrix(data = rcauchy(iter*s1,0,1),nrow = iter,ncol = s1)
sets1 <- apply(mat1,1,median)
hist(sets1)
s2 <- 5
mat2 <- matrix(data = rcauchy(iter*s2,0,1),nrow = iter,ncol = s2)
sets2 <- apply(mat2,1,median)
hist(sets2)
s3 <- 10
mat3 <- matrix(data = rcauchy(iter*s3,0,1),nrow = iter,ncol = s3)
sets3 <- apply(mat3,1,median)
hist(sets3)
s4 <-20
mat4 <- matrix(data = rcauchy(iter*s4,0,1),nrow = iter,ncol = s4)
sets4 <- apply(mat4,1,median)
hist(sets4)
I tried the following:
set.seed(1234)
iter <- 1000
size <- c(2,5,10,20)
for(i in 2:size){
for (j in 1:iter){
mat[] <- matrix(data = rcauchy(i*j,0,1),nrow=iter,ncol=i)
s <- apply(mat,1,median)
hist(s)
}
}
But it does not work, please help

The easies way is to wrap the creation of the matrix into a lapply function.
set.seed(123)
iter <- 1000
size <- c(2,5,10,20)
returnmatrix<-lapply(size, function(i){
mat<-matrix(data = rcauchy(i*iter,0,1),nrow=iter,ncol=i)
s <- apply(mat,1,median)
hist(s, main=paste("Histogram when S=", i))
mat
})
The lapply function will plot the histograms and will return the matrixes as list if additional processing is desired.

Related

For in function in R for different groups of rows

I have the following R objects:
y <- sample(c(0,2,2),1000,replace=T)
X <- matrix(runif(2000,0,2),ncol=2,byrow=T)*2
XX = t(X)%*%X
XY = as.numeric(t(X)%*%y)
YY = as.numeric(t(y)%*%y)
How can I run it to get several XX, XY and YY objects calculated with the first 10 rows, others with the rows 11 to 20, etc...?? Any ideas with a for in loop?
Thank you!
We can create lists to store different outputs. Create a sequence with a step of 10 and calculate the result in for loop.
len <- length(y)/10
XX_list <- vector('list', len)
XY_list <- vector('list', len)
YY_list <- vector('list', len)
vals <- seq(1, length(y), 10)
for(i in seq_along(vals)) {
inds <- vals[i]:(vals[i] + 9)
XX_list[[i]] <- t(X[inds, ]) %*% X[inds, ]
XY_list[[i]] = as.numeric(t(X[inds, ])%*% y[inds])
YY_list[[i]] = as.numeric(t(y[inds])%*% y[inds])
}

How to read 3 correlation matrix as array

I would like to read 3 independent correlation matrix in one array.
I have followed the as indicated in here
However, getting error and don’t why. I would appreciate if some one could see my code and help me.
Here are my codes and simulated data.
dataDir <- getwd()
## Each matrix is in a csv file
set.seed(22)
## m1
li.A <- matrix(rnorm(100), nrow = 20)
rownames(li.A) <- LETTERS[1:20]
colnames(li.A) <- paste0("S_", ncol = 1:5)
m1 <- cor(t(li.A))
write.csv(m1, file = “m1.csv")
# m2
set.seed(42)
pa.A <- matrix(rnorm(100), nrow = 20)
rownames(pa.A) <- LETTERS[1:20]
colnames(pa.A) <- paste0("S_", ncol = 1:5)
m2 <- cor(t(pa.A))
write.csv(m2, file = “m2.csv")
# m3
set.seed(44)
li.B <- matrix(rnorm(100), nrow = 20)
rownames(li.B) <- LETTERS[1:20]
colnames(li.B) <- paste0("S_", ncol = 1:5)
m3 <- cor(t(li.B))
write.csv(m3, file = “m3.csv")
fileList <- dir(path=dataDir,pattern = ".csv")
## Read all matrices into an array
A <- array(as.numeric(NA),dim=c(20,20,3)) # There are 3 matrices of size 20 x 20
for (i in 1:length(fileList)){
A[,,i] <- as.matrix(read.delim(file.path(dataDir,fileList[i]), sep = ';', header=TRUE, row.names=1))
}
here is the error.
Error in A[, , i] <- as.matrix(read.delim(file.path(dataDir, fileList[i]), :
replacement has length zero
Thank you!
The issue would be related to the sep = ';' instead it is sep="," and it returns a single string column instead of the multiple columns. Therefore, when we do the assignment with indexing, it showed the error
A <- array(as.numeric(NA),dim=c(20,20,3)) # There are 3 matrices of size 20 x 20
for (i in 1:length(fileList)){
A[,,i] <- as.matrix(read.delim(file.path(dataDir,fileList[i]),
sep = ',', header=TRUE, row.names=1))
}
dim(A)
#[1] 20 20 3

I want to use a list in a for loop code. list[[i]] works fine, but why doesn't res <- vector("list",n) work?

I am using a for loop to loop through two different matrices. The code looks like this:
x <- matrix(rnorm(1806),7,258)
x2 <- matrix(rnorm(1032),4,258)
samp_size <- 3
iter <- 1000
subs <- matrix(sample(1:nrow(x), samp_size*iter, replace=T),
ncol=samp_size, byrow=T)
subs2 <- matrix(sample(1:nrow(x2), samp_size*iter, replace=T),
ncol=samp_size, byrow=T)
for(j in 1:nrow(subs)){
ad <- x[subs[j,],]
ad1 <- x2[subs2[j,],]
rd <- rbind(ad,ad1)
dis <- dist(rd, method="euclidian")
#CV <- sd(unlist(rd), na.rm=TRUE)/mean(unlist(rd), na.rm=TRUE)*100
dis2 <- dis[dis!=0]
list[[j]] <- mean(dis2)
l <- unlist(list)
l <- na.omit(l)
sdis <- dist(ad, method="euclidian")
sdis2 <- sdis[sdis!=0]
res <- vector("list", 1000)
res[[j]] <- mean(sdis2)
l2 <- unlist(res)
l2 <- na.omit(l2)
}
list[[j]] works just fine.
The result of each iteration is added to it as a list element based on the value of j.
However, res[[j]] ends up being full of NULL with only the last element containing a value.
I am not sure what is happening here. I would like res[[j]] to behave the same way as list[[j]] does.
Help much appreciated.
Maybe initialize res:
# before the loop
res <- rep(list(NA),nrow(subs))
# or in the loop
res <- rep(list(NA),1000)
# or
res <- list(numeric(1000))

For Loop storing output as list to then combine into matrix

I have a list of matrices I would like to first convert into individual vectors then combine them into one large matrix. I have been trying to implement a for loop to do this and have been unable to do so with any success.
Example data: 5 10x10 matrices in a list
m1 <- matrix(1:100, nrow = 10, ncol = 10)
m2 <- matrix(1:100, nrow = 10, ncol = 10)
m3 <- matrix(1:100, nrow = 10, ncol = 10)
m4 <- matrix(1:100, nrow = 10, ncol = 10)
m5 <- matrix(1:100, nrow = 10, ncol = 10)
mylist <- list(m1, m2, m3, m4, m5)
I can turn an individual matrix into a vector using the following:
unlist(mylist[1])
My for loop is as follows, and currently outputs them all into a single vector:
z = list()
for (i in mylist[length(mylist)]) {
n <- unlist(mylist)
z <- c(n)
}
length(z)
[1] 500
The output I would like would be the df:
m1 <- unlist(mylist[1])
m2 <- unlist(mylist[2])
m3 <- unlist(mylist[3])
m4 <- unlist(mylist[4])
m5 <- unlist(mylist[5])
df <- cbind(m1, m2, m3, m4, m5)
Any help would be great! Thanks!
To use a for loop, I would do it like this:
z = list()
for (i in seq_along(mylist)) {
z[[i]] = c(mylist[[i]])
}
But when you're just applying a simple function to each list element, lapply is very nice:
z = lapply(mylist, c)
If you then want to cbind all of these vectors, we can either use Reduce or do.call:
do.call(what = cbind, args = z)
Reduce(f = cbind, x = z)
The do.call is equivalent to cbind(z[[1]], z[[2]], z[[3]], ...), and the Reduce is equivalent to cbind(z[[1]], cbind(z[[2]], cbind(z[[3]], ...))). Since cbind accepts any number of arguments, do.call is probably nicer. You would need Reduce if you wanted to add or multiply the vectors, for example.

Errors while using cbind with a matrix

I have a list of 40 data sets who all have the same columns. I want to bind the 7th column of each data set. I thought about doing this with a matrix using cbind. This is my code:
RetRates <- function(q) {
q <- matrix(nrow = 766, ncol = length(ListeActions),
data = rep(0, 766), byrow = TRUE)
s <- 0
for (i in 1:length(ListeActions)) {
x <- ListeActions[[i]]
q[,i] <- cbind(q[,i], x[,9]) ## I need the 9th column
}
return(q)
}
Hedi <- matrix(nrow = 766, ncol = length(ListeActions),
data = rep(0, 766), byrow = TRUE)
Hedi <- RetRates(Hedi)
I get these warnings :
Warning messages: 1: In replace(q[, i], 1:766, x[, 9]) : the number
of objects to be replaced is not a multiple of the size of the
replacement !
Let's take a smaller example: cbind the 5th columns of each of these 3 matrices
d1 <- matrix(runif(30), 5, 6)
d2 <- matrix(rnorm(30), 5, 6)
d3 <- matrix(rnorm(30), 5, 6)
First we put the 3 matrices in a list
M <- list(d1=d1, d2=d2, d3=d3)
Then we could use, as in your question, a for loop
res1 <- matrix(NA, nrow=5, ncol=length(M))
for (i in 1:length(M)) {
res1[, i] <- M[[i]][,5]
}
Or we could use some magical R functions to get the result in one slightly more obscure command
res2 <- do.call(cbind, lapply(M, "[",,5))

Resources