使用dplyr删除重复的行

时间:2014-04-09 10:22:39

标签: r dplyr

我有一个像这样的data.frame -

set.seed(123)
df = data.frame(x=sample(0:1,10,replace=T),y=sample(0:1,10,replace=T),z=1:10)
> df
   x y  z
1  0 1  1
2  1 0  2
3  0 1  3
4  1 1  4
5  1 0  5
6  0 1  6
7  1 0  7
8  1 0  8
9  1 0  9
10 0 1 10

我想根据前两列删除重复的行。预期产出 -

df[!duplicated(df[,1:2]),]
  x y z
1 0 1 1
2 1 0 2
4 1 1 4

我正在寻找使用dplyr包的解决方案。

6 个答案:

答案 0 :(得分:172)

以下是使用dplyr 0.3的解决方案。

library(dplyr)
set.seed(123)
df <- data.frame(
  x = sample(0:1, 10, replace = T),
  y = sample(0:1, 10, replace = T),
  z = 1:10
)

> df %>% distinct(x, y)
    x y z
  1 0 1 1
  2 1 0 2
  3 1 1 4

更新了dplyr 0.5

dplyr版本0.5 distinct()的默认行为仅返回...参数中指定的列。

要获得原始结果,您现在必须使用:

df %>% distinct(x, y, .keep_all = TRUE)

答案 1 :(得分:113)

注意dplyr现在包含distinct功能。

以下原始答案:


library(dplyr)
set.seed(123)
df <- data.frame(
  x = sample(0:1, 10, replace = T),
  y = sample(0:1, 10, replace = T),
  z = 1:10
)

一种方法是分组,然后只保留第一行:

df %>% group_by(x, y) %>% filter(row_number(z) == 1)

## Source: local data frame [3 x 3]
## Groups: x, y
## 
##   x y z
## 1 0 1 1
## 2 1 0 2
## 3 1 1 4

(在dplyr 0.2中,你不需要虚拟z变量,而且只是 能写row_number() == 1

我一直在考虑添加一个slice()函数 工作如下:

df %>% group_by(x, y) %>% slice(from = 1, to = 1)

也许unique()的变体可以让你选择哪一个 要使用的变量:

df %>% unique(x, y)

答案 2 :(得分:24)

为了完整起见,以下内容也有效:

df %>% group_by(x) %>% filter (! duplicated(y))

但是,我更喜欢使用distinct的解决方案,我怀疑它也更快。

答案 3 :(得分:2)

在R中选择减少数据集的列时,通常会得到重复数据。

这两行给出了相同的结果。每个输出一个唯一的数据集,只有两个选定的列:

distinct(mtcars, cyl, hp);

summarise(group_by(mtcars, cyl, hp));

答案 4 :(得分:0)

大多数时候,最好的解决方案是使用dplyr的distinct(),如前所述。

但是,这是另一种使用dplyr中的slice()函数的方法。

# Generate fake data for the example
  library(dplyr)
  set.seed(123)
  df <- data.frame(
    x = sample(0:1, 10, replace = T),
    y = sample(0:1, 10, replace = T),
    z = 1:10
  )

# In each group of rows formed by combinations of x and y
# retain only the first row

    df %>%
      group_by(x, y) %>%
      slice(1)

与使用distinct()函数的区别

此解决方案的优点在于,它可以使从原始数据帧保留的行明确化,并且可以与arrange()函数很好地配对。

假设您拥有客户销售数据,并且希望保留每个客户的一条记录,并且希望该记录成为他们最近一次购买的记录。然后您可以写:

customer_purchase_data %>%
   arrange(desc(Purchase_Date)) %>%
   group_by(Customer_ID) %>%
   slice(1)

答案 5 :(得分:0)

如果要查找重复的行,可以使用find_duplicates中的hablar

library(dplyr)
library(hablar)

df <- tibble(a = c(1, 2, 2, 4),
             b = c(5, 2, 2, 8))

df %>% find_duplicates()