views:

67

answers:

2

Hello

Imagine I've got 100 numeric matrixes with 5 columns each. I keep the names of that matrixes in a vector or list:

Mat <- c("GON1EU", "GON2EU", "GON3EU", "NEW4", ....)

I also have a vector of coefficients "coef",

coef <- c(1, 2, 2, 1, ...)

And I want to calculate a resulting vector in this way:

coef[1]*GON1EU[,1]+coef[2]*GON2EU[,1]+coef[3]*GON3EU[,1]+coef[4]*NEW4[,1]+.....

How can I do it in a compact way, using the the vector of names?

Something like:

coef*(Object(Mat)[,1])

I think the key is how to call an object from a string with his name and use and vectorial notation. But I don't know how.

+2  A: 

See help(get) and that's that.

If you'd given us a reproducible example I'd have said a bit more. For example:

> a=1;b=2;c=3;d=4
> M=letters[1:4]
> M
[1] "a" "b" "c" "d"
> sum = 0 ; for(i in 1:4){sum = sum + i * get(M[i])}
> sum
[1] 30

Put whatever you need in the loop, or use apply over the vector M and get the object:

> sum(unlist(lapply(M,function(n){get(n)^2})))
[1] 30
Spacedman
Hi. Thanks, but I don't know how to use it. Get doesn't seem to accept vector of names.
@user425895; `get()` won't, you need to wrap something around this to expand it to your `coef[1]*GON1EU[,1]+coef[2]*GON2EU[,1]+coef[3]*GON3EU[,1]+coef[4]*NEW4[,1]+.....` bit.
Gavin Simpson
+4  A: 

get() allows you to refer to an object by a string. It will only get you so far though; you'll still need to construct the repeated call to get() on the list matrices etc. However, I wonder if an alternative approach might be feasible? Instead of storing the matrices separately in the workspace, why not store the matrices in a list?

Then you can use sapply() on the list to extract the first column of each matrix in the list. The sapply() step returns a matrix, which we multiply by the coefficient vector. The column sums of that matrix are the values you appear to want from your above description. At least I'm assuming that coef[1]*GON1EU[,1] is a vector of length(GON1EU[,1]), etc.

Here's some code implementing this idea.

vec <- 1:4 ## don't use coef - there is a function with that name
mat <- matrix(1:12, ncol = 3)
myList <- list(mat1 = mat, mat2 = mat, mat3 = mat, mat4 = mat)
colSums(sapply(myList, function(x) x[, 1]) * vec)

Here is some output:

> sapply(myList, function(x) x[, 1]) * vec
     mat1 mat2 mat3 mat4
[1,]    1    1    1    1
[2,]    4    4    4    4
[3,]    9    9    9    9
[4,]   16   16   16   16
> colSums(sapply(myList, function(x) x[, 1]) * vec)
mat1 mat2 mat3 mat4 
  30   30   30   30

The above example suggest you create, or read in, your 100 matrices as components of a list from the very beginning of your analysis. This will require you to alter the code you used to generate the 100 matrices. Seeing as you already have your 100 matrices in your workspace, to get myList from these matrices we can use the vector of names you already have and use a loop:

Mat <- c("mat","mat","mat","mat")
## loop
for(i in seq_along(myList2)) {
    myList[[i]] <- get(Mat[i])
}
## or as lapply call - Kudos to Ritchie Cotton for pointing that one out!
## myList <- lapply(Mat, get)
myList <- setNames(myList, paste(Mat, 1:4, sep = ""))
## You only need:
myList <- setNames(myList, Mat)
## as you have the proper names of the matrices

I used "mat" repeatedly in Mat as that is the name of my matrix above. You would use your own Mat. If vec contains what you have in coef, and you create myList using the for loop above, then all you should need to do is:

colSums(sapply(myList, function(x) x[, 1]) * vec)

To get the answer you wanted.

Gavin Simpson
Thanks, I'll try.
Is it right "myList <- list(mat1 = mat, mat2 = mat, mat3 = mat, mat4 = mat)"?
I mean, you wrote the same thing on the right side of each equal
Yes - this is dummy data. I didn't want to have to create four different matrices. You have the different matrices already. If you aren't sure how to get your matrices into a list, let me know and I'll edit my answer to show this too.
Gavin Simpson
Hello. Can I just write myList <- list("GON1EU", "GON2EU", "GON3EU", "NEW4",...) ?
No, you'd need `myList <- list(get("GON1EU"), get("GON2EU"), get("GON3EU"), get("NEW4",...))` as per Spacedman's answer. You can do this in a loop if you already have your 100 separate matrices. I was seeing if you could rethink how you stored your data. I'll edit my answer to show you how you can make `myList` from the names of the matrices.
Gavin Simpson
You also wanna combine lapply/sapply with ?SetNames (referring to your latter comment.
ran2
@ucfagls: Simplify that `for` loop as `myList <- lapply(Mat, get)`.
Richie Cotton
@Richie Cotton - smacks head! How did I miss that one. Thanks!
Gavin Simpson