【问题标题】:R function to create band matrixR函数创建带状矩阵
【发布时间】:2011-03-03 04:47:11
【问题描述】:

我需要写两个函数toBand()replaceBand()

test3 <- toBand(test1,3)
test4 <- replaceBand(test1, toBand(test2,3))

得到下面的输出。

第一个使用 X 的下三角形返回对角线和同对角线元素的矩阵。第二个从提供的带状矩阵中的数据替换 X 中的相应元素。然后该函数返回修改后的 X。

我可以使用任何软件包来执行此操作吗?有关如何执行此操作的任何建议?

谢谢

> test1
     [,1]  [,2]  [,3]  [,4]  [,5]  [,6]
[1,] "a11" "a21" "a31" "a41" "a51" "a61"
[2,] "a21" "a22" "a32" "a42" "a52" "a62"
[3,] "a31" "a32" "a33" "a43" "a53" "a63"
[4,] "a41" "a42" "a43" "a44" "a54" "a64"
[5,] "a51" "a52" "a53" "a54" "a55" "a65"
[6,] "a61" "a62" "a63" "a64" "a65" "a66"
> test2
     [,1]    [,2]    [,3]    [,4]    [,5]    [,6]  
[1,] "*a11*" "*a21*" "*a31*" "*a41*" "*a51*" "*a61*"
[2,] "*a21*" "*a22*" "*a32*" "*a42*" "*a52*" "*a62*"
[3,] "*a31*" "*a32*" "*a33*" "*a43*" "*a53*" "*a63*"
[4,] "*a41*" "*a42*" "*a43*" "*a44*" "*a54*" "*a64*"
[5,] "*a51*" "*a52*" "*a53*" "*a54*" "*a55*" "*a65*"
[6,] "*a61*" "*a62*" "*a63*" "*a64*" "*a65*" "*a66*"
> test3
     [,1]  [,2]  [,3]  [,4]  [,5]  [,6]
[1,] "a11" "a22" "a33" "a44" "a55" "a66"
[2,] "a21" "a32" "a43" "a54" "a65" NA  
[3,] "a31" "a42" "a53" "a64" NA    NA  
[4,] "a41" "a52" "a63" NA    NA    NA  
> test4
     [,1]    [,2]    [,3]    [,4]    [,5]    [,6]  
[1,] "*a11*" "*a21*" "*a31*" "*a41*" "a51"   "a61" 
[2,] "*a21*" "*a22*" "*a32*" "*a42*" "*a52*" "a62" 
[3,] "*a31*" "*a32*" "*a33*" "*a43*" "*a53*" "*a63*"
[4,] "*a41*" "*a42*" "*a43*" "*a44*" "*a54*" "*a64*"
[5,] "a51"   "*a52*" "*a53*" "*a54*" "*a55*" "*a65*"
[6,] "a61"   "a62"   "*a63*" "*a64*" "*a65*" "*a66*"

【问题讨论】:

    标签: r matrix


    【解决方案1】:

    如果您不需要使用来自toBand 的输出,这很简单:

    replaceBand <- function(a, b, k) {
      swap <- abs(row(a) - col(a)) <= k
      a[swap] <- b[swap]
      a
    }
    

    制作矩阵来演示:

    test1 <- matrix(ncol=6, nrow=6)
    test1 <- matrix(paste("a", row(test1), col(test1), sep=""), nrow=6)
    test1b <- matrix(paste("a", col(test1), row(test1), sep=""), nrow=6)
    test1[upper.tri(test1)] <- test1b[upper.tri(test1b)]
    test2 <- matrix(paste("*", test1, "*", sep=""), nrow=6)
    

    输出完全符合要求:

    > replaceBand(test1, test2, 3)
    
         [,1]    [,2]    [,3]    [,4]    [,5]    [,6]   
    [1,] "*a11*" "*a21*" "*a31*" "*a41*" "a51"   "a61"  
    [2,] "*a21*" "*a22*" "*a32*" "*a42*" "*a52*" "a62"  
    [3,] "*a31*" "*a32*" "*a33*" "*a43*" "*a53*" "*a63*"
    [4,] "*a41*" "*a42*" "*a43*" "*a44*" "*a54*" "*a64*"
    [5,] "a51"   "*a52*" "*a53*" "*a54*" "*a55*" "*a65*"
    [6,] "a61"   "a62"   "*a63*" "*a64*" "*a65*" "*a66*"
    

    这里是toBandreplaceBand 的版本,它们的工作方式与所述相同。我想通过算术来准确计算出如何填充矩阵会更干净,但这是一种无需费力思考的方法。也许其他人会这样回答。

    toBand <- function(x,k) {
      n <- nrow(x)
      out <- matrix(nrow=n, ncol=n)
      out[row(out) + col(out) - 1 <= n] <- x[lower.tri(x, diag=TRUE)]
      out[1:(k+1),]
    }
    
    replaceBand <- function(a, b) {
      b[row(b)+col(b)-1 <= ncol(b)]
      swap <- abs(row(a) - col(a)) <= nrow(b) - 1
      a[swap & lower.tri(a, diag=TRUE)] <- b[row(b)+col(b)-1 <= ncol(b)]
      a[upper.tri(a)] <- t(a)[upper.tri(a)]
      a
    }
    

    【讨论】:

    • 何亚伦,谢谢您的回复。我还有一个天真的问题。如何为需要矩阵和 k 值的 S4“Band”类编写 initialize() 方法?它应该被定义为一个带有形式参数 (x, k) 的函数,并且应该将 X 的下三角元素放入对象中。
    • @user635034:我只使用过 S3 方法。如果您不清楚通​​常的 S4 文档,不妨试试 Hadley 的 wiki:github.com/hadley/devtools/wiki/S4
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-14
    • 2019-09-15
    • 2019-11-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多