1

有人可以告诉我为什么会收到此错误以及如何解决吗?

这是代码

我要做的是删除与 1 相关联的行,如果该列小于 10

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))
c4=c(rep(1,6),rep(0,34))
x=matrix(cbind(a0,a,b,c0,c1,c2,c3,c4),nrow=40,ncol=8)
nam <- paste("V",2:9,sep="")
colnames(x)<-nam
dat <- cbind(y=rnorm(40,50,7),x)
#===================================
toSum <- colSums(dat)
Col <- Val <- NULL
for(i in 1:length(toSum)){
if(toSum[i]<10){
Col <- c(Col,colnames(dat)[i])
Val <- c(Val,toSum[i])}
}
cs <- colSums(dat) < 10
indx <- dat[,which(cs)]==0
for(i in 1:dim(indx)[2]){
datnw <- dat[indx[,i],]
dat <- datnw}
datnw2 <- dat[, -which(cs)]

谢谢

4

1 回答 1

2

如果我正确理解你想要达到的目标,你最好这样写:

cs <- colSums(dat) < 10
dat[rowSums(dat[,cs]) == 0, !cs]

这意味着:对于总和小于 10 的任何列(以下称为“小列”),删除该列中具有 1 的任何行。因此,您只保留所有这些小列中为零的行。您也删除了小列,因为它们在任何情况下都只包含零。

在您的代码中,indx是一个具有 40 行的逻辑数据框,每行输入一个,输入中的每个小列一个列。您使用第一列idx删除第一短列中带有 1 的行。这会产生一个新值dat它比原始值短几行。在循环的下一次迭代中,您使用第二个逻辑向量来尝试删除更多行。但这行不通:在第一次迭代之后,dat有不到 40 行,但第二列仍然有所有 40 行。这就是导致错误的原因:您正在使用长度为 40 的逻辑向量为少于 40 个元素的向量下标。

您可以使用以下表达式将您的三列组合indx成一个适合为感兴趣的行下标的向量:

apply(indx, 1, all)

对于每列中TRUE的那些行,这将在其结果中具有一个值。TRUE但是,我想我更喜欢上面的代码,因为它写起来要短得多。更喜欢后者的最可能原因是您的数据框可能包含负数,因此行总和为零并不意味着行全为零。在您的示例数据中没有问题。

于 2012-09-18T15:11:34.770 回答