删除组内的重复项?

时间:2019-09-05 16:11:19

标签: r

示例数据代码:

    mydf<-data.frame(Group_ID=c("337", "337", "201", "201", "470", "470", "999", "999"), 
             Timestamp=c("A", "A", "B", "B", "C", "D", "E", "F"), 
             MU=c("1", "1", "2", "3", "4", "4", "5", "6"))

示例数据框:

  Group_ID Timestamp MU
1      337         A  1
2      337         A  1
3      201         B  2
4      201         B  3
5      470         C  4
6      470         D  4
7      999         E  5
8      999         F  6

在“ Group_ID”中,我只想保留“ Timestamp”和“ MU”都不重复的条目。因此,在该示例中,仅保留行7和8 (“ Group_ID” 999具有“ Timestamp”和“ MU”的唯一条目)。

我的一些尝试:

mydf<-mydf %>%
  group_by(Group_ID) %>%
  filter(unique(Timestamp))

返回错误:

  

“参数2过滤条件不等于逻辑矢量”

如果这行得通,那么我将使用unique(MU)

再次运行它
mydf<-mydf %>%
  group_by(Group_ID) %>%
  mydf[!duplicated(mydf$Timestamp, fromLast = TRUE),]

返回错误:

  

“逻辑索引向量的长度必须为1或3(列数),而不是8”

(再次,我将使用MU重新运行代码)

我已经看过类似的问题,但是没有找到具有相同场景的问题。提前谢谢了。

3 个答案:

答案 0 :(得分:5)

如果我们使用filter,则需要逻辑向量。 unique的输出只是该列(character类)的唯一元素。因此,它将无法正常工作。我们可以使用duplicated来获得重复元素的逻辑矢量,取反(!)。这样TRUE-> FALSE,反之亦然,只获得第一个非重复元素

library(dplyr)
mydf %>% 
   group_by(Group_ID) %>% 
   filter(!(duplicated(Timestamp, fromLast = TRUE)| duplicated(Timestamp))) 

或基于行数按“ Group_ID”,“时间戳”和filter分组

mydf %>%
   group_by(Group_ID, Timestamp) %>%
   filter(n() == 1)

如果我们只需要'999''Group_ID'

mydf %>% 
  group_by(Group_ID) %>%
  filter_at(vars(Timestamp,  MU),  all_vars(n_distinct(.) == n()))
# A tibble: 2 x 3
# Groups:   Group_ID [1]
#  Group_ID Timestamp MU   
#  <fct>    <fct>     <fct>
#1 999      E         5    
#2 999      F         6    

或直接使用distinct

distinct(mydf, Group_ID, Timestamp, .keep_all = TRUE)

答案 1 :(得分:2)

foo = function(x, f){
    ave(as.numeric(as.factor(x)),
        f,
        FUN = function(y) length(unique(y)) == length(y))
}

inds = Reduce("&", lapply(mydf[c("Timestamp", "MU")],
                          function(x) foo(x, mydf$Group_ID) == 1))

mydf[inds,]
#  Group_ID Timestamp MU
#7      999         E  5
#8      999         F  6

答案 2 :(得分:0)

这是一个基本解决方案:

is.unique <- function(x) !(duplicated(x) | duplicated(x, fromLast = TRUE))
mydf[is.unique(mydf[1:2]) & is.unique(mydf[c(1,3)]),]
#>   Group_ID Timestamp MU
#> 7      999         E  5
#> 8      999         F  6