2012-10-26 28 views
8

我有一个很大的mxn矩阵,我已经确定了线性相关列。但是,我想知道R中是否有方法用线性无关的方式编写线性相关列。由于它是一个很大的矩阵,所以根据检查是不可能的。如何使用线性无关列写入矩阵中的线性相关列?

这里是一个玩具的矩阵类型的例子。

> mat <- matrix(c(1,1,0,1,0,1,1,0,0,1,1,0,1,1,0,1,0,1,0,1), byrow=TRUE, ncol=5, nrow=4) 
> mat 
     [,1] [,2] [,3] [,4] [,5] 
[1,] 1 1 0 1 0 
[2,] 1 1 0 0 1 
[3,] 1 0 1 1 0 
[4,] 1 0 1 0 1 

这里很明显,x3 = x1-x2,x5 = x1-x4。我想知道是否有一种自动的方式来获得更大的矩阵。

谢谢!

+1

此功能可以帮助你:http://www.inside-r.org/packages/cran/heplots/docs/gsorth –

+1

@BenBolker而且,由于这种联系现在死了只是在这里寻找'gsorth'函数:https://cran.r-project.org/web/packages/heplots/heplots.pdf – Dason

回答

9

我确定有更好的方法,但我觉得喜欢玩这个。基本上我会在开始时进行检查,看看输入矩阵是否为满列排序以避免在满秩时进行不必要的计算。之后,我从前两列开始,检查该子矩阵是否为全列,如果是,则检查第一列,等等。一旦我们发现某个不是全列列的子矩阵,我会回到前一列中的最后一列,它告诉我们如何构建第一列的线性组合以获得最后一列。

我的功能现在不是很干净,可以做一些额外的检查,但至少这是一个开始。

mat <- matrix(c(1,1,0,1,0,1,1,0,0,1,1,0,1,1,0,1,0,1,0,1), byrow=TRUE, ncol=5, nrow=4) 


linfinder <- function(mat){ 
    # If the matrix is full rank then we're done 
    if(qr(mat)$rank == ncol(mat)){ 
     print("Matrix is of full rank") 
     return(invisible(seq(ncol(mat)))) 
    } 
    m <- ncol(mat) 
    # cols keeps track of which columns are linearly independent 
    cols <- 1 
    for(i in seq(2, m)){ 
     ids <- c(cols, i) 
     mymat <- mat[, ids] 
     if(qr(mymat)$rank != length(ids)){ 
      # Regression the column of interest on the previous 
      # columns to figure out the relationship 
      o <- lm(mat[,i] ~ mat[,cols] + 0) 
      # Construct the output message 
      start <- paste0("Column_", i, " = ") 
      # Which coefs are nonzero 
      nz <- !(abs(coef(o)) <= .Machine$double.eps^0.5) 
      tmp <- paste("Column", cols[nz], sep = "_") 
      vals <- paste(coef(o)[nz], tmp, sep = "*", collapse = " + ") 
      message <- paste0(start, vals) 
      print(message) 
     }else{ 
      # If the matrix subset was of full rank 
      # then the newest column in linearly independent 
      # so add it to the cols list 
      cols <- ids 
     } 
    } 
    return(invisible(cols)) 
} 

linfinder(mat) 

这给

> linfinder(mat) 
[1] "Column_3 = 1*Column_1 + -1*Column_2" 
[1] "Column_5 = 1*Column_1 + -1*Column_4" 
+0

谢谢!这很好! –

+0

@Dason我在研究我的问题时遇到了这个答案(非常相似,只是附加需求)@ http://stackoverflow.com/questions/43596486/how-to-identify-columns-that-are-sums-的-其他柱-IN-A-数据集。在这个讨论中加入你也会很棒。 – Aurimas