在R中选择没有缺失值的行

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次迭代。
对于冗长的帖子我们深表歉意,但不胜感激。

不考虑函数的机制,如果您想返回没有 NA 值的 sm,那么 return(na.omit(sm)) 就可以解决问题。 - mnel
@mnel 谢谢,我忘记了这个命令。因为我的主要问题是在原始代码中的下一个命令上,我正在检查数据中是否存在共线性以适合或不适合模型,“所以我强制执行的条件是如果存在共线性,请让我知道在哪个迭代中并且不适合该模型,然后开始下一个迭代”。还有在特定迭代次数保存到文件的问题。 - Falcon-StatGuy
1个回答

7
在返回sm之前,您可以使用complete.cases()过滤掉具有NA值的行。它看起来像sm[complete.cases(sm),]。该函数返回一个TRUE/FALSE值的逻辑向量,强制R不返回那些带有FALSE的值。
此外,看起来您在定义baditers后没有做任何事情。我可以注释掉所有涉及baditers的行,您的函数似乎完全正常...也许这是您代码以前版本的遗留问题?
更新:
以下是使用complete.cases()的更新函数。请注意,我还注释掉了与baditers相关的所有内容,以说明它当前在您的代码中没有起作用。
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(),它会告诉我们结果对象的#行和#列:

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

所以一个奇异点和一个矩阵,有19行7列,我漏掉了什么?

至于你的另一个问题,关于写出东西,你是否知道write.table()和相关函数中的append参数?帮助页面告诉我们:如果为TRUE,则将输出附加到文件。如果为FALSE,则销毁任何现有名称的文件。

更新2

这里是使用write.table()中的append=TRUE的示例。

#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

我尝试了你的方法,但没有成功,还有其他建议吗?关于在特定迭代次数保存到文件怎么样? - Falcon-StatGuy
@frespider - 我添加了你修改后的函数,看起来还有什么遗漏吗? - Chase
请问您能否更详细地解释一下write.table和append的用法? - Falcon-StatGuy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接