6

我是 R 和 for 循环的新用户。我正在尝试从数据中取样并检查是否存在共线列。我想在该迭代中记录共线列存在并将其记录在向量(baditr)中。另外,我想打印一行表明“共线性在迭代 i 处”。然后我希望代码跳转到第二次迭代并继续运行。对于每次迭代,我希望代码保存矩阵相应行中的列的总和。

我的问题是我得到了错误迭代的 NA。我的意图是让糟糕的迭代根本不包含在我的矩阵中。这是我的代码:

a0=rep(1,40)
a=rep(0:1,20)
b=c(rep(1,20),rep(0,20))
c0=c(rep(0,12),rep(1,28))
c1=c(rep(1,5),rep(0,35))
c2=c(rep(1,8),rep(0,32))
c3=c(rep(1,23),rep(0,17))
da=matrix(cbind(a0,a,b,c0,c1,c2,c3),nrow=40,ncol=7)
sing <- function(nrw){
  sm <- matrix(NA,nrow=nrw,ncol=ncol(da))
  baditr <- NULL
  for(i in 1:nrw){
    ind <- sample(1:nrow(da), nrow(da),replace =TRUE)
    smdat <- da[ind,]
    evals <- eigen(crossprod(smdat))$values
    if(any(abs(evals) < 1e-7)){
      baditr <- c(baditr,i)
      cat("singularity occurs at", paste(i),"\n")
      next
    }
  sm[i,] <- apply(smdat,2,sum)
  }
  return(sm)
}
sing(20)

我将得到以下输出:

singularity occurs at 9 
singularity occurs at 13 
      [,1] [,2] [,3] [,4] [,5] [,6] [,7]
 [1,]   40   23   22   25    5    8   26
 [2,]   40   20   18   30    4    7   22
 [3,]   40   19   24   28    6    7   25
 [4,]   40   19   22   30    6    9   26
 [5,]   40   12   26   26    8   13   30
 [6,]   40   17   16   27    7   10   19
 [7,]   40   20   17   33    3    5   19
 [8,]   40   22   19   28    4    9   23
 [9,]   NA   NA   NA   NA   NA   NA   NA
[10,]   40   21   24   28    3    6   27
[11,]   40   21   16   31    2    4   22
[12,]   40   21   21   26    3    6   23
[13,]   NA   NA   NA   NA   NA   NA   NA
[14,]   40   18   16   29    2    7   22
[15,]   40   24   18   30    6    9   21
[16,]   40   23   18   29    4    8   21
[17,]   40   17   25   25    3    8   29
[18,]   40   22   28   23    9   14   30
[19,]   40   25   23   25    7   11   30
[20,]   40   20   23   27    7   10   26

我希望我的矩阵看起来像这样:

singularity occurs at 9 
singularity occurs at 13 
      [,1] [,2] [,3] [,4] [,5] [,6] [,7]
 [1,]   40   23   22   25    5    8   26
 [2,]   40   20   18   30    4    7   22
 [3,]   40   19   24   28    6    7   25
 [4,]   40   19   22   30    6    9   26
 [5,]   40   12   26   26    8   13   30
 [6,]   40   17   16   27    7   10   19
 [7,]   40   20   17   33    3    5   19
 [8,]   40   22   19   28    4    9   23
[10,]   40   21   24   28    3    6   27
[11,]   40   21   16   31    2    4   22
[12,]   40   21   21   26    3    6   23
[14,]   40   18   16   29    2    7   22
[15,]   40   24   18   30    6    9   21
[16,]   40   23   18   29    4    8   21
[17,]   40   17   25   25    3    8   29
[18,]   40   22   28   23    9   14   30
[19,]   40   25   23   25    7   11   30
[20,]   40   20   23   27    7   10   26

作为故障保险,我还将感谢您将一定数量的迭代保存到文件(例如,50 次迭代)的任何信息,一旦产生下一个迭代次数,我可以覆盖这些信息。意思是,我将前 50 次迭代保存到一个文件中,然后一旦产生了第二轮 50 次迭代,它们就会覆盖第一轮,因此,我的文件现在有 100 次迭代。

对不起,很长的帖子。但提前谢谢。

4

1 回答 1

7

在返回之前sm,您可以使用 过滤掉具有NA值的行complete.cases()。它看起来像sm[complete.cases(sm),]. 该函数返回 TRUE/FALSE 值的逻辑向量,这会强制 R 不返回具有 FALSE 的值。

此外,在定义它之后,您看起来并没有做任何事情baditers。我可以注释掉所有引用的行,baditers并且您的函数似乎工作得很好......也许它是旧代码迭代的遗留物?

更新

这是您使用complete.cases(). 请注意,我还注释掉了所有相关的内容,baditr以说明它当前在您的代码中没有做任何事情。

sing <- function(nrw){
  sm <- matrix(NA,nrow=nrw,ncol=ncol(da))
  #baditr <- NULL
  for(i in 1:nrw){
    ind <- sample(1:nrow(da), nrow(da),replace =TRUE)
    smdat <- da[ind,]
    evals <- eigen(crossprod(smdat))$values
    if(any(abs(evals) < 1e-7)){
      #baditr <- c(baditr,i)
      cat("singularity occurs at", paste(i),"\n")
      next
    }
    sm[i,] <- apply(smdat,2,sum)
  }
  return(sm[complete.cases(sm),])
}

现在让我们运行这个函数,我正在环绕dim()函数调用,它将告诉我们结果对象的#rows 和#columns:

> dim(sing(20))
singularity occurs at 6 
[1] 19  7

所以一个奇点和一个 19 行 7 列的矩阵,我错过了什么吗?

至于你关于写东西的另一个问题,你知道append参数 to write.table()and friends 吗?帮助页面告诉我们If TRUE, the output is appended to the file. If FALSE, any existing file of the name is destroyed.

更新 2

append = TRUE这是一个使用in的示例write.table()

#Matrix 1 definition and write to file
x <- matrix(1:9, ncol = 3)
write.table(x, "out.txt", sep = "\t", col.names = TRUE, row.names = FALSE)
#Matrix 2 definition and write to same file with append = TRUE
x2 <- matrix(10:18, ncol = 3)
write.table(x2, "out.txt", sep = "\t", col.names = FALSE, row.names = FALSE, append = TRUE)
#read consolidated data back in to check if it's right
x3 <- read.table("out.txt", header = TRUE)

结果是

  V1 V2 V3
1  1  4  7
2  2  5  8
3  3  6  9
4 10 13 16
5 11 14 17
6 12 15 18
于 2012-09-13T02:23:00.797 回答