0

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.

TooTone
  • 7,129
  • 5
  • 34
  • 60
tobias sch
  • 369
  • 2
  • 15
  • I cannot completely understand your question. Do you have all those matrix in a list? – BBrill Aug 09 '14 at 13:43
  • No, they are single matrices, but their names are matrix1, matrix2, matrix3, etc.. Does this help? – tobias sch Aug 09 '14 at 13:46
  • 3
    Well, if you don't have a list, you should. Having a bunch of single variable names like that is just inefficient in R, especially when you want to perform similar operations on them all. You should rarely need to use `get()/assign()` in R especially if you are new to R. That's usually a sign you are not doing things "the R way". How did you create all these variables? – MrFlick Aug 09 '14 at 13:54
  • It is strange to have all those matrix in such a non organised way. This is the true problem. After, it is possible to found workarounds... – BBrill Aug 09 '14 at 13:54
  • please see how I got these matrices, thanks already for the great support! – tobias sch Aug 09 '14 at 14:00
  • Where are these matrices? Hopefully they're in a `list` – Rich Scriven Aug 09 '14 at 15:16

3 Answers3

4

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.

dayne
  • 7,504
  • 6
  • 38
  • 56
1
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.
akrun
  • 874,273
  • 37
  • 540
  • 662
  • I did not see your solution and already assigned the "go" to dayne. Sorry! Thank you, it would work as well! – tobias sch Aug 09 '14 at 14:57
0

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

BBrill
  • 1,922
  • 17
  • 17