我已将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
我只希望其中一行,因为其他行在第一列中具有相同的数据。
答案 0 :(得分:163)
对于那些来这里寻找重复行删除的一般答案的人,请使用!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
答案 1 :(得分:154)
只需将数据框与您需要的列隔离,然后使用唯一函数: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.
答案 2 :(得分:63)
dplyr包中的函数distinct()
执行任意重复删除,允许指定重复变量(如本问题所示)或考虑所有变量。
数据:强>
dat <- data.frame(a = rep(c(1,2),4), b = rep(LETTERS[1:4],2))
删除指定列重复的行:
library(dplyr)
dat %>% distinct(a, .keep_all = TRUE)
a b
1 1 A
2 2 B
删除与其他行完全重复的行:
dat %>% distinct
a b
1 1 A
2 2 B
3 1 C
4 2 D
答案 3 :(得分:25)
data.table
软件包还拥有unique
和duplicated
方法,并附带一些其他功能。
unique.data.table
和duplicated.data.table
方法都有一个额外的by
参数,可让您传递character
或integer
列名称向量或其地点分别
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
这些方法的另一个重要特征是大型数据集的巨大性能提升
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
答案 4 :(得分: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)
解决方案:
library(sqldf)
sqldf('SELECT DISTINCT * FROM df')
输出:
a b
1 A 1
2 A 2
3 B 4
4 B 1
5 C 2
答案 5 :(得分:5)
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)), ]
X1 X2 X3
1 2 9 6
2 4 6 7
答案 6 :(得分:5)
您还可以使用dplyr
的{{1}}函数!它往往比替代选项更有效,尤其是在您有大量观察数据的情况下。
distinct()
答案 7 :(得分:3)
或者您可以使用tidyr
将第4列和第5列中的数据嵌套到一行中:
library(tidyr)
df %>% nest(V4:V5)
# A tibble: 1 × 4
# V1 V2 V3 data
# <fctr> <int> <int> <list>
#1 platform_external_dbus 202 16 <tibble [5 × 2]>
现在删除了第2列和第3列重复项以进行统计分析,但是您已将第4列和第5列数据保存为tibble,并且可以使用unnest()
随时返回到原始数据框。
答案 8 :(得分:3)
这是一个非常简单,快速的dplyr
/ tidy
解决方案:
删除完全相同的行:
library(dplyr)
iris %>%
distinct(.keep_all = TRUE)
删除仅在某些列中相同的行:
iris %>%
distinct(Sepal.Length, Sepal.Width, .keep_all = TRUE)
答案 9 :(得分:1)
删除数据框的重复行
library(dplyr)
mydata <- mtcars
# Remove duplicate rows of the dataframe
distinct(mydata)
在此数据集中,没有单个重复行,因此它返回的行数与mydata中的行数相同。
基于一个变量删除重复行
library(dplyr)
mydata <- mtcars
# Remove duplicate rows of the dataframe using carb variable
distinct(mydata,carb, .keep_all= TRUE)
.keep_all函数用于将所有其他变量保留在输出数据帧中。
基于多个变量删除重复行
library(dplyr)
mydata <- mtcars
# Remove duplicate rows of the dataframe using cyl and vs variables
distinct(mydata, cyl,vs, .keep_all= TRUE)
.keep_all函数用于将所有其他变量保留在输出数据帧中。
(来自:http://www.datasciencemadesimple.com/remove-duplicate-rows-r-using-dplyr-distinct-function/)
答案 10 :(得分:0)
这个问题也可以通过从每个组中选择第一行来解决,其中该组是我们要选择唯一值的列(在共享示例中,它只是第一列)。
使用基数R:
subset(df, ave(V2, V1, FUN = seq_along) == 1)
# V1 V2 V3 V4 V5
#1 platform_external_dbus 202 16 google 1
在dplyr
library(dplyr)
df %>% group_by(V1) %>% slice(1L)
或使用data.table
library(data.table)
setDT(df)[, .SD[1L], by = V1]
如果我们需要根据多个列查找唯一的行,只需将上述各列的名称添加到分组部分即可。
数据
df <- structure(list(V1 = structure(c(1L, 1L, 1L, 1L, 1L),
.Label = "platform_external_dbus", class = "factor"),
V2 = c(202L, 202L, 202L, 202L, 202L), V3 = c(16L, 16L, 16L,
16L, 16L), V4 = structure(c(1L, 4L, 3L, 5L, 2L), .Label = c("google",
"hughsie", "localhost", "space-ghost.verbum", "users.sourceforge"
), class = "factor"), V5 = c(1L, 1L, 1L, 8L, 1L)), class = "data.frame",
row.names = c(NA, -5L))