2012-09-18 351 views
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)] 

感謝

回答

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值。不過,我想我更喜歡我的代碼,因爲它寫得更短。選擇後者的最可能原因是如果您的數據幀可能包含負數,那麼零的行和不意味着全零行。您的示例數據中沒有問題。