开发者

R: Call matrixes from a vector of string names?

Imagine I've got 100 numeric matrixes with 5 columns each. I keep the names of that matrixes in a vec开发者_开发知识库tor 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.


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.


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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜