代码之家  ›  专栏  ›  技术社区  ›  skan

R: 从字符串名称向量调用矩阵?

  •  0
  • skan  · 技术社区  · 15 年前

    假设我有100个数字矩阵,每个矩阵有5列。

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

    我还有一个系数向量“coef”,

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

    我想用这种方法计算一个结果向量:

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

    我怎样才能用一种简洁的方式,用名字的矢量来做呢?

    类似于:

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

    我认为关键是如何从一个字符串中调用一个对象,这个字符串有他的名字、用法和矢量表示法。但我不知道怎么做。

    2 回复  |  直到 15 年前
        1
  •  6
  •   Gavin Simpson    15 年前

    get() 允许您通过字符串引用对象。不过,这只会让您走到目前为止;您仍然需要在列表矩阵等上构造对get()的重复调用。不过,我想知道是否可以使用其他方法?与其将矩阵单独存储在工作区中,为什么不将矩阵存储在列表中?

    那你就可以用 sapply() 在列表上提取列表中每个矩阵的第一列。这个 step返回一个矩阵,我们用它乘以系数向量。该矩阵的列和是您希望从上述描述中得到的值。至少我认为 coef[1]*GON1EU[,1] 是一个向量 length(GON1EU[,1]) 等等。

    下面是一些实现这个想法的代码。

    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)
    

    以下是一些输出:

    > 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
    

    上面的示例建议您从分析的一开始就创建或读入100个矩阵作为列表的组成部分。这将要求您更改用于生成100个矩阵的代码。既然你的工作区已经有了100个矩阵 myList 从这些矩阵中,我们可以使用已有的名称向量并使用循环:

    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
    

    "mat" 反复地 Mat 因为那是我上面矩阵的名字。你会用你自己的 . 如果 vec 包含你所拥有的 coef 迈利斯特 for 在上面循环,那么您需要做的就是:

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

    为了得到你想要的答案。

        2
  •  2
  •   Spacedman    15 年前

    看救命,就这样。

    > 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
    

    把你需要的东西放在循环中,或者在向量M上使用apply得到对象:

    > sum(unlist(lapply(M,function(n){get(n)^2})))
    [1] 30