删除重复的行

use*_*691 136 r duplicates r-faq

我已经将CSV文件读入R data.frame.某些行在其中一列中具有相同的元素.我想删除该列中重复的行.例如:

platform_external_dbus          202           16                     google        1
platform_external_dbus          202           16         space-ghost.verbum        1
platform_external_dbus          202           16                  localhost        1
platform_external_dbus          202           16          users.sourceforge        8
platform_external_dbus          202           16                    hughsie        1
Run Code Online (Sandbox Code Playgroud)

我只想要其中一行,因为其他行在第一列中具有相同的数据.

Meh*_*len 172

对于来这里寻找重复行删除的一般答案的人,请使用!duplicated():

a <- c(rep("A", 3), rep("B", 3), rep("C",2))
b <- c(1,1,2,4,1,1,2,2)
df <-data.frame(a,b)

duplicated(df)
[1] FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE  TRUE

> df[duplicated(df), ]
  a b
2 A 1
6 B 1
8 C 2

> df[!duplicated(df), ]
  a b
1 A 1
3 A 2
4 B 4
5 B 1
7 C 2
Run Code Online (Sandbox Code Playgroud)

回答:从R数据框中删除重复的行

  • 这保留了第一个出现的值并删除了其余的重复项,对吧?或者它随机删除值? (2认同)
  • 如果您只对某些列中的重复项感兴趣,例如第 1 列和第 2 列,我们可以使用 `df[!duplicated(df[, 1:2])]` (2认同)

Ant*_*ico 157

只需将数据框与您需要的列隔离,然后使用唯一函数:D

# in the above example, you only need the first three columns
deduped.data <- unique( yourdata[ , 1:3 ] )
# the fourth column no longer 'distinguishes' them, 
# so they're duplicates and thrown out.
Run Code Online (Sandbox Code Playgroud)

  • 请注意,这将删除除前三个列之外的所有列。 (7认同)
  • @ user1897691将其标记为正确然后;)[观看此](http://www.screenr.com/fCs8)如果您喜欢,请查看[twotorials.com](http://twotorials.com) (6认同)

Sam*_*rke 71

该函数distinct()dplyr包执行任意重复的去除,从而允许重复变量的规范(如在这个问题),或者考虑到所有变量.

数据:

dat <- data.frame(a = rep(c(1,2),4), b = rep(LETTERS[1:4],2))
Run Code Online (Sandbox Code Playgroud)

删除指定列重复的行:

library(dplyr)
dat %>% distinct(a, .keep_all = TRUE)

  a b
1 1 A
2 2 B
Run Code Online (Sandbox Code Playgroud)

删除与其他行完全重复的行:

dat %>% distinct

  a b
1 1 A
2 2 B
3 1 C
4 2 D
Run Code Online (Sandbox Code Playgroud)


Dav*_*urg 27

data.table软件包还uniqueduplicated一些额外的功能,它自己的方法.

无论是unique.data.tableduplicated.data.table方法有一个额外的by参数,它允许你传递一个characterinteger分别列名或它们的位置矢量

library(data.table)
DT <- data.table(id = c(1,1,1,2,2,2),
                 val = c(10,20,30,10,20,30))

unique(DT, by = "id")
#    id val
# 1:  1  10
# 2:  2  10

duplicated(DT, by = "id")
# [1] FALSE  TRUE  TRUE FALSE  TRUE  TRUE
Run Code Online (Sandbox Code Playgroud)

这些方法的另一个重要特征是对较大数据集的巨大性能增益

library(microbenchmark)
library(data.table)
set.seed(123)
DF <- as.data.frame(matrix(sample(1e8, 1e5, replace = TRUE), ncol = 10))
DT <- copy(DF)
setDT(DT)

microbenchmark(unique(DF), unique(DT))
# Unit: microseconds
#       expr       min         lq      mean    median        uq       max neval cld
# unique(DF) 44708.230 48981.8445 53062.536 51573.276 52844.591 107032.18   100   b
# unique(DT)   746.855   776.6145  2201.657   864.932   919.489  55986.88   100  a 


microbenchmark(duplicated(DF), duplicated(DT))
# Unit: microseconds
#           expr       min         lq       mean     median        uq        max neval cld
# duplicated(DF) 43786.662 44418.8005 46684.0602 44925.0230 46802.398 109550.170   100   b
# duplicated(DT)   551.982   558.2215   851.0246   639.9795   663.658   5805.243   100  a 
Run Code Online (Sandbox Code Playgroud)


use*_*745 11

这是一个非常简单、快速的dplyr解决tidy方案:

删除完全相同的行:

library(dplyr)
iris %>% 
  distinct(.keep_all = TRUE)
Run Code Online (Sandbox Code Playgroud)

删除仅在某些列中相同的行:

iris %>% 
  distinct(Sepal.Length, Sepal.Width, .keep_all = TRUE)

Run Code Online (Sandbox Code Playgroud)

  • 这是一个很好的方法,可以保留在管道中。对于上面的第一个选项,需要注意的是,您不需要 .keep_all = TRUE,因为保留 unique 不合格,据我所知,它会评估整个数据帧。 (2认同)

Ami*_*pta 6

一般的答案可以是例如:

df <-  data.frame(rbind(c(2,9,6),c(4,6,7),c(4,6,7),c(4,6,7),c(2,9,6))))



new_df <- df[-which(duplicated(df)), ]
Run Code Online (Sandbox Code Playgroud)

输出:

      X1 X2 X3
    1  2  9  6
    2  4  6  7
Run Code Online (Sandbox Code Playgroud)

  • 使用“-which”时要小心,如果没有重复,这会导致错误,使用“df[!(duplicated(df)),]”可能更安全。 (4认同)

小智 6

您还可以使用dplyrdistinct()功能!它往往比替代选项更有效,尤其是在您有大量观察数据的情况下。

distinct_data <- dplyr::distinct(yourdata)
Run Code Online (Sandbox Code Playgroud)

  • 这与 Sam Firke 的答案相同,但细节较少。 (4认同)

mpa*_*nco 5

sqldf:

# Example by Mehdi Nellen
a <- c(rep("A", 3), rep("B", 3), rep("C",2))
b <- c(1,1,2,4,1,1,2,2)
df <-data.frame(a,b)
Run Code Online (Sandbox Code Playgroud)

解:

 library(sqldf)
    sqldf('SELECT DISTINCT * FROM df')
Run Code Online (Sandbox Code Playgroud)

输出:

  a b
1 A 1
2 A 2
3 B 4
4 B 1
5 C 2
Run Code Online (Sandbox Code Playgroud)

  • 设置整个 SQL 数据库是什么意思?这是主要优点之一:“使用 sqldf,用户不必执行以下操作,所有这些操作都会自动完成:数据库设置、编写定义每个表的创建表语句、从数据库导入和导出'。这不是一个最佳解决方案,但对于熟悉 SQL 的人来说很方便。 (2认同)