R loop over multiple matrices

穿精又带淫゛_ 提交于 2021-01-29 10:16:41

问题


I have 472 matrices with 405 columns each (matrix1 , ... , matrix400) and want to have 472 new matrices with only the first 244 columns of that matrix. How can I do that? I tried:

for (i in 1:472) {
assign(paste("new_matrix",i,sep=""), matrix[[i]][,c(1:244)])
}

I created the matrices by splitting one dataframe by one identifier (for the groups):

for (i in 1:472){
   assign(paste("matrix", i, sep=""), subset(data, ID==i))
}

Somehow I cannot speak to each matrix but I have no clue how I can do that.


回答1:


You clearly should take a different approach. Assigning all of the individual matricies is NOT a good approach. But here is one way you could do that...

mat1 <- matrix(1:6, 2, 3)
mat2 <- matrix(2:7, 2, 3)

example_func <- function(mati) {

  mat_name <- as.name(paste0("mat", mati))
  bquote(.(mat_name) <- .(mat_name)[ , 1:2])

}

for (i in 1:2) eval(example_func(i))

However, using eval can complicated because you have to be very careful about environments, especially if used within functions. As an example try running lapply(1:2, function(x) eval(example_func(x))) instead of using the for-loop and look at how the results differ.

To take a better approach, look at ?split.

some_data <- data.frame(ID = rep(1:4, each = 4),
                        V1 = 1:16,
                        v2 = letters[1:16])

split(some_data, list(some_data$ID))

Then you could use lapply to iterate through your subsets and subset further. Or, better yet, just subset the original data.frame down to the columns you want first, then use split.




回答2:


matrix1 <- matrix(1:25, 5,5)
matrix2 <- matrix(26:50, 5,5)

Suppose, I want to subset the first 3 columns of the above matrices,

list2env(
   setNames(
          lapply(mget(ls(pattern="matrix")), `[`, ,1:3),
                  paste("new", ls(pattern="matrix"),sep="_")), 
                                               envir=.GlobalEnv)

  new_matrix1
  #     [,1] [,2] [,3]
  #[1,]    1    6   11
  #[2,]    2    7   12
  #[3,]    3    8   13
  #[4,]    4    9   14
  #[5,]    5   10   15

  new_matrix2
  #      [,1] [,2] [,3]
  # [1,]   26   31   36
  # [2,]   27   32   37
  # [3,]   28   33   38
  # [4,]   29   34   39
  # [5,]   30   35   40
  • ls(pattern="matrix") will output [1] "matrix1" "matrix2"
  • mget get the values stored in the above matrices as a list
  • Subset the first 3 columns of matrices in list using lapply(...,[,1:3)
  • Change the name of the list elements from matrix1, matrix2 by using setNames and paste
  • Use list2env to create new objects new_matrix1, new_matrix2. However, in your case, this would create 472 new_matrices in the global environment. I would prefer to subset the matrices in a list do all the necessary calculations within the list. Then you could use write.table or write.matrix from library(MASS) to write the list elements to file.



回答3:


If you started with a dataframe

here is how you can end with a list of matrix splitted by the groups (and having its name) and with the number of row you want:

library("ddply")
dlply(iris, .(Species), function(x) x[1:10,])

iris is a dummy dataframe you have with base R; Species is your factor group



来源:https://stackoverflow.com/questions/25219169/r-loop-over-multiple-matrices

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!