删除重复项,保持最频繁的行

时间:2018-04-04 20:54:15

标签: r dplyr

我想对我的数据进行重复数据删除,保留最常出现的行。如果行中有一个平局,我不关心返回哪个 - 按字母顺序或数字顺序排在第一位。我想通过idvar

小组来完成此操作

MRE:

df <- data.frame(
  id = rep("a", 8),
  var = c(rep("b", 4), rep("c", 4)),
  val = c("d", "d", "d", "e", "f", "f", "g", "g")
)

> df
  id var val
1  a   b   d
2  a   b   d
3  a   b   d
4  a   b   e
5  a   c   f
6  a   c   f
7  a   c   g
8  a   c   g

应该是:

  id var val
1  a   b   d
2  a   c   f

我正在处理大型数据集和tidyverse管道链,因此最好使用dplyr解决方案。

6 个答案:

答案 0 :(得分:3)

使用tablewhich.max提取mode

df %>% 
    group_by(id, var) %>% 
    summarise(val = {t <- table(val); names(t)[which.max(t)] })

# A tibble: 2 x 3
# Groups:   id [?]
#  id    var   val  
#  <fct> <fct> <chr>
#1 a     b     d    
#2 a     c     f  

在基础R中执行此操作的另一种方法:直接创建三向列联表,然后沿第三轴找到最大列:

apply(table(df), c(1, 2), function(v) names(v)[which.max(v)])

#   var
#id  b   c  
#  a "d" "f"

将其转换为数据框:

as.data.frame.table(
    apply(table(df), c(1, 2), function(v) names(v)[which.max(v)])
)

#  id var Freq
#1  a   b    d
#2  a   c    f

答案 1 :(得分:2)

我怀疑这是否更快,但另一种选择是

df %>% 
    group_by(id, var) %>% 
    filter(row_number() == rle(as.character(val))$lengths %>% 
                                {sum(.[1:which.max(.)])})

答案 2 :(得分:2)

使用 dplyr

library(dplyr)

df %>% 
  group_by(id, var, val) %>% 
  summarise(n = n()) %>% 
  group_by(id, var) %>% 
  arrange(-n) %>% 
  slice(1) %>% 
  ungroup() %>% 
  select(-n)

# # A tibble: 2 x 3
#   id    var   val  
#   <fct> <fct> <fct>
# 1 a     b     d    
# 2 a     c     f   

答案 3 :(得分:2)

一个选项可能是使用tablemax

library(dplyr)
df %>% group_by(id, var) %>%
  filter(table(val) == max(table(val))) %>%
  slice(1)
# # A tibble: 2 x 3
# # Groups: id, var [2]
# id     var    val   
# <fctr> <fctr> <fctr>
# 1 a      b      d     
# 2 a      c      g    

注: a c g是平局的情况。每个OP在绑定的情况下可以返回任何记录。

答案 4 :(得分:1)

这是我的尝试:

library(dplyr)
df %>%
  group_by(id,var,val) %>%
  mutate(n=n()) %>%
  arrange(desc(n)) %>%
  group_by(id,var) %>%
  filter(row_number()==1) %>%
  select(-n)

`

答案 5 :(得分:1)

使用count的dplyr解决方案:

library(dplyr)

df %>%
  count(id,var,val,sort = T) %>%
  group_by(id,var) %>%
  summarize_at("val",head,1)

# # A tibble: 2 x 3
#       id    var    val
#   <fctr> <fctr> <fctr>
# 1      a      b      d
# 2      a      c      f

或者可能更惯用但更长:

df %>%
  count(id,var,val,sort = T) %>%
  group_by(id,var) %>%
  slice(1) %>%
  select(-n) %>%
  ungroup

tally使用相同的输出语法略有不同:

df %>%
  group_by(id,var,val) %>%
  tally(sort = T) %>%
  slice(1) %>%
  select(-n) %>%
  ungroup

和基础解决方案:

df2 <- aggregate(x ~ .,cbind(df,x=1),sum)
aggregate(val ~ id+var, df2[order(-df2$x),],head,1)
#   id var val
# 1  a   b   d
# 2  a   c   f