2017-05-08 63 views
3

我有兩個數據幀。刪除在另一個數據幀的相應行中具有特定值的數據幀中的行

第一個包含我的實際數據,我們稱之爲數據。第二個用作指示符矩陣,它使用if-else語句構造,該語句檢查包含至少1或2的一行值的發生,我們稱之爲指示

下面是一個例子:

col1<-c(1,3,1,3,2) 
col2<-c(3,4,2,3,"") 
col3<-c(1,3,"","","") 
col4<-c(2,"","","","") 

data<-data.frame(cbind(col1,col2,col3,col4)) 

> data 
    col1 col2 col3 col4 
    1 3 1 2 
    3 4 3  
    1 2   
    3 3   
    2 

數據的行必須包含至少一個1或2,所以這裏是我的功能:

remove<-function(x){ 

    if (((x[1] == "1") | (x[1] == "2")) | ((x[2] == "1") | (x[2] == "2")) 
     | ((x[3] == "1") | (x[3] == "2")) | ((x[4] == "1") | (x[4] == "2"))){ 
    return(0) 
    } 

else{ 
    return(1) 
} 
} 

indic<-data.frame(apply(data,1,remove)) 

> indic 
     y 
1  0 
2  1 
3  0 
4  1 
5  0 

通過觀察數據,第2行和第4行不包含至少1或2,這由標記確認。

我想刪除在數據,其對應於行2和4中印度語行2和4。我已經試過如下:

finalMatrix<-class(array) 

for(i in 1:nrow(indic)){ 
    if (indic[i,1] == "1"){ 
    finalMatrix = data[-i,] 
    } 
    else{ 
    data[i,] = data[i,] 
    } 
} 

然而,我的輸出是這樣的:

> finalMatrix 
    col1 col2 col3 col4 
    1 3 1 2 
    3 4 3  
    1 2     
    2  

,有效地消除了第四行只。我認爲這可能與我必須在每次迭代後創建一個新的數據幀有關,但問題是迭代長度會改變。

想知道如果我在正確的軌道上與我的代碼...任何建議將是可愛的。我一直在推翻這一點。

-Soph

+3

我不確定我是否理解這個問題。你想要像'finalMatrix < - data [indic!=「1」,]'? – Vandenman

+1

'finalMatrix < - 數據[其中(印度語== 0),]'將是也可以在此情況下 –

+1

爲什麼不只是'數據[rowSums(數據== 「1」 |數據== 「2」)> 0, ]'?你沒有正確地使用矢量化,而'for'循環效率很差。此外,似乎沒有理由強迫你的價值觀「人物」;缺少值使用'NA'。 – nicola

回答

1

你可以嘗試生成TRUE/FALSE縮放的矢量,而不是你的印度語載體,其中包含0/1。這使得最終過濾更加明顯。

> data 
    col1 col2 col3 col4 
1 1 3 1 2 
2 3 4 3  
3 1 2   
4 3 3   
5 2   

採用any會給您輕鬆訪問的12行的內容。第二個any會告訴你,如果滿足兩個條件之一。通過所有行的apply()的運行,如果第二個參數被設置爲1

indic <- apply(data, 1, function(row) { 
    any(c(any(row == 1), any(row == 2))) 
}) 


> indic 
[1] TRUE FALSE TRUE FALSE TRUE 

> data[indic,] 
    col1 col2 col3 col4 
1 1 3 1 2 
3 1 2   
5 2 

至於你的問題的標題所暗示的印度語載體也可以應用到另一個數據幀,但在這裏,重要的是要注意具有相同尺寸的數據幀和指示向量或者針對向量回收。

拿起@ nicola建議使用矢量化。

data[rowSums(data=="1" | data=="2")>0,] 

這樣做可以最有效地保留循環並創建indic。儘管從rowSums(data=="1" | data=="2")>0發出的TRUE/FALSE矢量仍然可以保存在變量中。

相關問題