transform a matrix to another one using loop - r

I have a matrix (11x42) and I would like to apply a function for each column one by one and put the result back in a new 11x42 matrix with a new name and modified column names.
I am not used to loops so I am a bit struggling. Here is what I have so far, but not working.
for (i in 1:ncol(matrix))
{
res[[i]] <-residuals(lm(matrix[,i]~HW))
}
I would like to also use the function paste0("new_", i) to change the names of each column.
Here I was trying to create 42 vectors (res1 to res 42) that I would cbind into a new matrix. But it's not working. And I am pretty sure that could be done within the loop as well.
Thanks in advance!

Since its a matrix you should use apply with margin 2, i.e.
new_mat <- apply(your_mat, 2, function(i) residuals(lm(i~HW)))
colnames(new_mat) <- paste0('new_', colnames(your_mat))

Related

Changing column names of a matrix in R without using colnames()

im new to R and was wondering if there is a way to assign names to columns in a matrix without using the colnames() function
#creating two vectors
player <- c(rep('dark',5),rep('light',5))
piece <-c('king','queen','pawn','pawn','knight','bishop','king','rook','pawn','pawn')
#creating a matrix
matrix2 <- c(player, piece)
dim(matrix2) <- c(10, 2)
#this would work perfectly but i was looking for an alternate method which doesn't uses
#colnames() function
colnames(matrix2) <- c('player','piece')
I also know that using cbind() would give me a matrix with column names as those of the two vectors
matrix2<-cbind(player,piece)
But I don't want to create my matrix with the cbind() function. I wanted to know if there is a way to name the colunmns of the matrix other than using the colnames() function after creating the matrix like I have created above.
Difficult to answer. Do you mean like this?
dimnames(matrix2) <- list(c(1:10), c("player", "piece"))
EDIT, without "naming" row_names (see comments, #akrun mentioned that earlier):
dimnames(matrix2) <- list(NULL, c("player", "piece"))

How can I store for loop results in dataframe in R

I have checked previous answers regarding to my question but my question seems to be more complicated. The following is my loop:
for(i in 2:45)
{
abs(meta1[,i]-median(meta1[,i], na.rm=T))/(mad(meta1[,i], constant
= 1, na.rm=T)*1.483)
}
meta1 is my data frame. I want to apply my for loop to column 2 to 45 (each is numeric vector) in my data frame. I want to store the resulting vectors in a new data frame. Could somebody point me out a direction? Thanks.
Initialize a list, store the values in each iteration in the list elements and finally cbind it to create a matrix
lst <- setNames(vector('list', 43), 2:45)
for(i in 2:45)
{
lst[[i]] <- abs(meta1[,i]-median(meta1[,i], na.rm=T))/(mad(meta1[,i],
constant = 1, na.rm=T)*1.483)
}
do.call(cbind, lst)
You are not providing example data. That makes this guess work. But you could probably approach it like this:
meta2 <- meta1
for(i in 2:45)
{
meta2[,i] <- abs(meta1[,i]-median(meta1[,i], na.rm=T))/(mad(meta1[,i], constant = 1, na.rm=T)*1.483)
}

Apply function on each element in two Dataframes using R

How do I apply a function on each elements over two Dataframes?
In the following example I want to prevent the double for-loop:
for(m in 1:nrow(DF1)) {
for(n in 1:ncol(DF1)) {
mySeq <- seq(DF1[m,n], DF2[m,n], 0.01)
# Do the rest with mySeq ...
}
}
My purpose is to create sequences between each element of two dataframes with the same index.
The probably fastest solution and first thougth was mySeq <- seq(DF1, DF2, 0.01). But this doest'n work because the arguments of seq(from,to) have to be of length 1.
My second try was to use apply(). This doesn't work because it only applies on one dataframe. Then I searched for an appropriate apply solution and found mapply(). With mapply is it possible to apply on two dataframes, but there is no possibility to apply on each elements in the dataframe but rather on the rows of da dataframe. And I dont want to take use of nested apply() calls.
So my question is how to code the example shown above without using a double for-loop nor a nested apply?
I'm not sure what function you are trying to apply on the elements but I have used the sweep() function for something similar in the past. For example:
df = data.frame(x = 1:10, y = 1:10, z = 1:10)
sweep(df, 1:2, 1)
Here sweep goes through every element of df and subtracts 1 but you can specify your own function to operate on the elements. Then you can either tie your 2 data frames together and use sweep() or apply it separately.

need to assign variables some values in a loop in R

I need to assign variables some values in a loop
Eg:
abc_1<-
abc_2<-
abc_3<-
.....
something like:
for(i in 1:20)
{
paste("abc",i,sep="_")<-some calculated value
}
I have tried to use paste as above but it doesn't work.
How could this be done.Thanks
assign() and paste0() should help you.
for example:
object_names <- paste0("abc",1:20)
for (i in 1:20){
assign(object_names[i],runif(40))
}
assign() takes the string in object_names and assigns the function in the second argument to each name. When you place a numeric vector inside of paste0() it gives back a character vector of concatenated values for each value in the numeric vector.
edit:
As Gregor says below, this is much better to do in a list because:
It will be faster.
When making a large number of things you probably want to do the same thing to each of them. lapply() is very good at this.
For example:
N <- 20
# create random numbers in list
abcs <- lapply(1:N,function(i) runif(40))
# multiply each vector in list by 10
abc.mult <- lapply(1:length(abcs), function(i) abcs[[i]] * 10)

Operating on multiple matrices in a for loop using R

I have 1000 matrices named A1, A2, A3,...A1000.
In a for loop I would like to simply take the colMeans() of each matrix:
for (i in 1:1000){
means[i,]<-colMeans(A1)
}
I would like to do this for each matrix Ax. Is there a way to put Ai instead of A1 in the for loop?
So, one way is:
for (i in 1:1000){
means[i,]<-colMeans(get(paste('A', i, sep = '')))
}
but I think that misses the point of some of the comments, i.e., you probably had to do something like this:
csvs = lapply(list.files('.', pattern = 'A*.csv'), function(fname) {
read.csv(fname)
})
Then the answer to your question is:
means = lapply(csvs, colMeans)
I don't completely understand, but maybe you have assigned each matrix to a different variable name? That is not the best structure, but you can recover from it:
# Simulate the awful data structure.
matrix.names<-paste0('A',1:1000)
for (name in matrix.names) assign(name,matrix(rnorm(9),ncol=3))
# Pull it into an appropriate list
list.of.matrices<-lapply(matrix.names,get)
# Calculate the column means
column.mean.by.matrix<-sapply(list.of.matrices,colMeans)
You initial question asks for a 'for loop' solution. However, there is an easy way to get the desired
result if we use an 'apply' function.
Perhaps putting the matrices into a list, and then applying a function would prove worthwhile.
### Create matrices
A1 <- matrix(1:4, nrow = 2, ncol = 2)
A2 <- matrix(5:9, nrow = 2, ncol = 2)
A3 <- matrix(11:14, nrow = 2, ncol = 2)
### Create a vector of names
names <- paste0('A', 1:3)
### Create a list of matrices, and assign names
list <- lapply(names, get)
names(list) <- names
### Apply the function 'colMeans' to every matrix in our list
sapply(list, colMeans)
I hope this was useful!
As others wrote already, using a list is perhaps your best option. First you'll need to place your 1000 matrices in a list, most easily accomplished using a for-loop (see several posts above). Your next step is more important: using another for-loop to calculate the summary statistics (colMeans).
To apply a for-loop through an R object, in general you can do one of the two options:
Loop over by indices: for example:
for(i in 1:10){head(mat[i])} #simplistic example
Loop "directly"
for(i in mat){print(i)} #simplistic example
In the case of looping through R lists, the FIRST option will be much easier to set up. Here is the idea adapted to your example:
column_means <- rep(NA,1000) #empty vector to store column means
for (i in 1:length(list_of_matrices)){
mat <- list_of_matrices[[i]] #temporarily store individual matrices
##be sure also to use double brackets!
column_means <- c(column_means, colMeans(mat))

Resources