2017-03-07 68 views
2

我有以下的數據幀刪除行如果是一樣的前一行,有一列的例外

x <- data.frame(id = c(1:6), 
       a = c('a', 'b', 'b', 'a', 'a', 'c'), 
       b = rep(2, 6), 
       c = c(5, 4, 4, 5, 5, 2)) 

> x 
    id a b c 
1 1 a 2 5 
2 2 b 2 4 
3 3 b 2 4 
4 4 a 2 5 
5 5 a 2 5 
6 6 c 2 2 

我想

id a b c 
1 1 a 2 5 
2 2 b 2 4 
4 4 a 2 5 
6 6 c 2 2 

要求落得的是,我要刪除該行如果與前一行相同,則列id除外。如果它與列上一列相同,但不是前一列,我不想擺脫它。例如,id4與id1相同,但未被刪除,因爲它不是立即在它之上。

任何幫助,將不勝感激

回答

2

我們可以使用base R

x[!c(FALSE, !rowSums(x[-1, -1] != x[-nrow(x), -1])),] 
# id a b c 
#1 1 a 2 5 
#2 2 b 2 4 
#4 4 a 2 5 
#6 6 c 2 2 
+0

這將工作,但我有它在一個通用的功能,我不能保證id列將是第一列,所以會危險使用這種方法 – user1165199

+1

@ user1165199如果您需要使用名稱'nm1 < - setdiff(名稱(x),「id」); x [!c(FALSE,!rowSums(x [-1,nm1]!= x [-nrow(x),nm1])),]'' – akrun

2

這裏是dplyr使用lag功能的一種方式。這個想法是創建一個關鍵列,並檢查它是否與以前一樣。

library(dplyr) 
x %>% 
    mutate(key=paste(a, b, c, sep="|")) %>% 
    filter(key != lag(key, default="0")) %>% 
    select(-key) 
+0

感謝傑森,但是在我的實際情況下,我有更多的列不僅僅是一個,b和c。有沒有辦法將它們全部命名? – user1165199

+1

我認爲在這種情況下我們需要非標準的評估。但是,我沒有想出使用'mutate_'創建密鑰的方法。我最終得到的是:'x $ key < - apply(x [names(x [-1])],1,function(x)paste(x,collapse =「|」))''。 – JasonWang