Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to remove columns from each matrix in a list of matrices in R?

I am not very familiar with using the list function in R. This is my first use of a list of matrices. I am trying to remove the same columns from each matrix in a list of matrices but I am not sure how this works with the indexing in R.

Right now I have 8 matrices in a list. Each matrix is [120, 56]. I would like to remove rows columns 17-40 and 49-56 from each matrix. Therefore, I would end up with a list of 8 matrices of [120, 24].

Here is an example of the matrix list I have:

MatrixList <- list(maxT = matrix(1:56, 120, 56, byrow = TRUE),
        minT = matrix(1:56, 120, 56, byrow = TRUE),
        meanT = matrix(1:56, 120, 56, byrow = TRUE),
        rain24 = matrix(1:56, 120, 56, byrow = TRUE),
        rain5d = matrix(1:56, 120, 56, byrow = TRUE),
        maxT2 = matrix(1:56, 120, 56, byrow = TRUE),
        minT2 = matrix(1:56, 120, 56, byrow = TRUE),
        meanT2 = matrix(1:56, 120, 56, byrow = TRUE))

I know this seems like a simple problem but I'm a novice and am just not sure how to use a combination of for loops and internal indexing to remove columns. I'd rather learn how to do this efficiently, rather than doing it for each matrix individually and then creating the list.

Any help would be appreciated. Thanks!

like image 752
djhocking Avatar asked Apr 22 '12 19:04

djhocking


2 Answers

As is often the case, @DWin gets in early with an excellent answer. Here is an alternative that my simple mind finds easier to comprehend.

You can use lapply to traverse your list, and then standard subsetting using the [ operator.

Rather than using [ operator as a function (as @DWin suggests), I prefer writing an anonymous function inside lapply that looks exactly like the operation you would perform to transform a single element of your list (i.e. subset a single matrix):

mls <- lapply(MatrixList, function(x)x[-c(17:40, 49:56), ])
str(mls)

List of 8
 $ maxT  : int [1:88, 1:56] 1 1 1 1 1 1 1 1 1 1 ...
 $ minT  : int [1:88, 1:56] 1 1 1 1 1 1 1 1 1 1 ...
 $ meanT : int [1:88, 1:56] 1 1 1 1 1 1 1 1 1 1 ...
 $ rain24: int [1:88, 1:56] 1 1 1 1 1 1 1 1 1 1 ...
 $ rain5d: int [1:88, 1:56] 1 1 1 1 1 1 1 1 1 1 ...
 $ maxT2 : int [1:88, 1:56] 1 1 1 1 1 1 1 1 1 1 ...
 $ minT2 : int [1:88, 1:56] 1 1 1 1 1 1 1 1 1 1 ...
 $ meanT2: int [1:88, 1:56] 1 1 1 1 1 1 1 1 1 1 ...
like image 138
Andrie Avatar answered Sep 30 '22 13:09

Andrie


lapply() is the function to use and the "trick" is to use "TRUE" as the first argument to get all of the rows followed by negative indexing to remove the columns:

smallerMtx <- lapply(MatrixList, "[", TRUE, -c(17:40 , 49:56))
str(smallerMtx )
#------------
List of 8
 $ maxT  : int [1:120, 1:24] 1 1 1 1 1 1 1 1 1 1 ...
 $ minT  : int [1:120, 1:24] 1 1 1 1 1 1 1 1 1 1 ...
 $ meanT : int [1:120, 1:24] 1 1 1 1 1 1 1 1 1 1 ...
 $ rain24: int [1:120, 1:24] 1 1 1 1 1 1 1 1 1 1 ...
 $ rain5d: int [1:120, 1:24] 1 1 1 1 1 1 1 1 1 1 ...
 $ maxT2 : int [1:120, 1:24] 1 1 1 1 1 1 1 1 1 1 ...
 $ minT2 : int [1:120, 1:24] 1 1 1 1 1 1 1 1 1 1 ...
 $ meanT2: int [1:120, 1:24] 1 1 1 1 1 1 1 1 1 1 ...

I guess we need to resolve whether you really want rows or columns remove. (You said columns in the first sentence but later seemed to say rows. The numeric parts of your example/request suggested columns to be removed, but perhaps you come from a programming tradition where columns are specified first????

like image 26
IRTFM Avatar answered Sep 30 '22 13:09

IRTFM