2016-07-13 162 views
1

在一個大型數據框中,我想刪除一行,其中第6列中有1。此外,該行之後的行也應該被刪除。任何人有答案?有條件地刪除一行,然後在另一個R

1  1  neutral   3 450 0 
    2  1   con   1 538 0 
    3  1  neutral   3 609 0 
    4  1   inc   0 451 0 
    5  1   inc   0 413 0 
    6  1  neutral   3 425 1 
    7  1   inc   0 514 0 
    8  1   con   1 569 0 

所以結果應該是這樣的:

1  1  neutral   3 450 0 
2  1   con   1 538 0 
3  1  neutral   3 609 0 
4  1   inc   0 451 0 
5  1   inc   0 413 0 
8  1   con   1 569 0 

我想這一點,但顯然這是不正確的:

while (i<=nrow(Pb)){ 
    if (Pb[i,6]==0 && Pb1[i-1,6]==0) { 
    newfile <- Pb[i,] 
    } 
    i <- i+1 
} 
+1

'library(data.table); setDT(dt)[,V6:= V6 + shift(V6,1L,type =「lag」)] [V6!= 1 | is.na(V6)]' –

+1

鬼鬼祟祟。不錯的一個@akrun,我不知道將'V6'改爲一個布爾值會讓你使用轉移到dt的子集。 –

回答

3

這裏是一個解決方案,首先提取要刪除的行:

rem<-which(Pb[,6]==1) 

然後你就可以刪除這些並通過執行以下操作:

Pb<-Pb[-c(rem,rem+1),] 

如果您擔心1可能出現在最後一行,並且想讓事物具有唯一性:

rem<-which(Pb[,6]==1) 
rem<-c(rem,rem+1) 
rem<-rem[rem<nrow(Pb)] 
Pb<-Pb[-rem,] 
+0

如果在最後一行有1,這將會中斷 –

+0

這是真的,我會編輯它以避免這種情況。 – DeveauP

+0

其實我錯了,只會發出警告。我的錯! –

2

您可以使用lagfilter功能從dplyr

df 
# V1 V2  V3 V4 V5 V6 
# 1 1 1 neutral 3 450 0 
# 2 2 1  con 1 538 0 
# 3 3 1 neutral 3 609 0 
# 4 4 1  inc 0 451 0 
# 5 5 1  inc 0 413 0 
# 6 6 1 neutral 3 425 1 
# 7 7 1  inc 0 514 0 
# 8 8 1  con 1 569 0 

library(dplyr) 
df %>% filter(V6 != 1, lag(V6, default = 0) != 1) 

# V1 V2  V3 V4 V5 V6 
# 1 1 1 neutral 3 450 0 
# 2 2 1  con 1 538 0 
# 3 3 1 neutral 3 609 0 
# 4 4 1  inc 0 451 0 
# 5 5 1  inc 0 413 0 
# 6 8 1  con 1 569 0 

數據

df <- structure(list(V1 = 1:8, V2 = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L 
), V3 = structure(c(3L, 1L, 3L, 2L, 2L, 3L, 2L, 1L), .Label = c("con", 
"inc", "neutral"), class = "factor"), V4 = c(3L, 1L, 3L, 0L, 
0L, 3L, 0L, 1L), V5 = c(450L, 538L, 609L, 451L, 413L, 425L, 514L, 
569L), V6 = c(0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L)), .Names = c("V1", 
"V2", "V3", "V4", "V5", "V6"), class = "data.frame", row.names = c(NA, 
-8L)) 
0

我做了一個數據幀:

dfm <- data.frame(a=rnorm(8), b=rbinom(8,1,.2)) 

#dfm <- structure(list(a = c(-1.06507365382823, 0.64103474967184, 0.0525921813159307, 
0.0465414259158497, -0.65811357438377, -0.466590684535497, -0.246266056446691, 
-0.397561700830275), b = c(1L, 0L, 0L, 1L, 0L, 0L, 0L, 0L)), .Names = c("a", 
"b"), row.names = c(NA, -8L), class = "data.frame") 
    dfm 
      a b 
1 -1.6687530 0 
2 -1.1303493 1 
3 0.1415896 0 
4 1.8102502 1 
5 -1.5421675 0 
6 0.1462142 0 
7 0.0821345 0 
8 0.4063876 0 

在其()函數工作得很好了這些問題:

rows_with_ones <- which(dfm$b == 1) 
    subequent_rows <- rows_with_ones+1 
    rows_to_remove <- c(rows_with_ones,subequent_rows) 

,並使用子集的基礎R,以消除那些行

dfm2 <- dfm[-rows_to_remove,] 
    dfm2 
      a b 
1 -1.6687530 0 
6 0.1462142 0 
7 0.0821345 0 
8 0.4063876 0 

Alternati vely,你可以做到這一點更快,用更少的按鍵(但也許不是那麼容易讀人)與簡易R構造子集:

dfm2 <- dfm[dfm$b!=1,] 

這種讀取類似,「子集DFM由治所在DFM的專欄」 B 「不等於1,然後分配該對象DFM2」

1

我們可以使用data.table

library(data.table) 
setDT(df)[!df[, {i1 <- .I[!!V6]; .(c(i1,i1+1))}]$V1] 
# V1 V2  V3 V4 V5 V6 
#1: 1 1 neutral 3 450 0 
#2: 2 1  con 1 538 0 
#3: 3 1 neutral 3 609 0 
#4: 4 1  inc 0 451 0 
#5: 5 1  inc 0 413 0 
#6: 8 1  con 1 569 0 

或者使用shift

setDT(df)[!V6 & shift(!V6, fill = TRUE)]  
# V1 V2  V3 V4 V5 V6 
#1: 1 1 neutral 3 450 0 
#2: 2 1  con 1 538 0 
#3: 3 1 neutral 3 609 0 
#4: 4 1  inc 0 451 0 
#5: 5 1  inc 0 413 0 
#6: 8 1  con 1 569 0 
相關問題