在 data.frame 中显示重复记录并省略单个记录
Posted
技术标签:
【中文标题】在 data.frame 中显示重复记录并省略单个记录【英文标题】:Display duplicate records in data.frame and omit single ones 【发布时间】:2012-12-25 19:22:48 【问题描述】:我一直在努力解决如何在 R 中仅选择重复的 data.frame 行。 例如,我的 data.frame 是:
age=18:29
height=c(76.1,77,78.1,78.2,78.8,79.7,79.9,81.1,81.2,81.8,82.8,83.5)
Names=c("John","John","John", "Harry", "Paul", "Paul", "Paul", "Khan", "Khan", "Khan", "Sam", "Joe")
village <- data.frame(Names, age, height)
Names age height
John 18 76.1
John 19 77.0
John 20 78.1
Harry 21 78.2
Paul 22 78.8
Paul 23 79.7
Paul 24 79.9
Khan 25 81.1
Khan 26 81.2
Khan 27 81.8
Sam 28 82.8
Joe 29 83.5
我想看到如下结果:
Names age height
John 18 76.1
John 19 77.0
John 20 78.1
Paul 22 78.8
Paul 23 79.7
Paul 24 79.9
Khan 25 81.1
Khan 26 81.2
Khan 27 81.8
感谢您的宝贵时间...
【问题讨论】:
【参考方案1】:使用duplicated
两次的解决方案:
village[duplicated(village$Names) | duplicated(village$Names, fromLast = TRUE), ]
Names age height
1 John 18 76.1
2 John 19 77.0
3 John 20 78.1
5 Paul 22 78.8
6 Paul 23 79.7
7 Paul 24 79.9
8 Khan 25 81.1
9 Khan 26 81.2
10 Khan 27 81.8
by
的替代解决方案:
village[unlist(by(seq(nrow(village)), village$Names,
function(x) if(length(x)-1) x)), ]
【讨论】:
@SvenHohenstein,这个答案的代表一直在跳跃。也许OP没有意识到只能接受一个答案;)【参考方案2】:village[ duplicated(village),]
【讨论】:
【参考方案3】:我发现@Sven 的答案使用重复的“最整洁”,但您也可以通过许多其他方式做到这一点。这里还有两个:
使用table()
和子集,方法是将列表> 1 的名称与第一列中的名称匹配:
village[village$Names %in% names(which(table(village$Names) > 1)), ]
使用ave()
以稍微不同的方式“制表”,但以相同的方式进行子集:
village[with(village, ave(as.numeric(Names), Names, FUN = length) > 1), ]
【讨论】:
【参考方案4】:或者,您可以在 dplyr 管道中使用分组和汇总。
代码行数更多,计算成本可能更高。但是,优点是您可以通过多列的复合键找到重复的行,而不是仅从一列中找到重复的行。
library(tidyverse)
a <- c(8, 18, 19, 19, 19, 20, 30, 32, 32)
b <- c(1950, 1965, 1981, 1971, 1981, 1999, 1969, 1994, 1999)
c <- c(1, 2, 3, 4, 5, 6, 7, 8, 9)
df <- data.frame(a, b, c)
df
# Description:df[,3] [9 × 3]
# a
# <dbl>
# b
# <dbl>
# c
# <dbl>
# 8 1950 1
# 18 1965 2
# 19 1981 3
# 19 1971 4
# 19 1981 5
# 20 1999 6
# 30 1969 7
# 32 1994 8
# 32 1999 9
# 9 rows
df[duplicated(df$a) | duplicated(df$a, fromLast = T), ]
# Description:df[,3] [5 × 3]
#
#
# a
# <dbl>
# b
# <dbl>
# c
# <dbl>
# 3 19 1981 3
# 4 19 1971 4
# 5 19 1981 5
# 8 32 1994 8
# 9 32 1999 9
# 5 rows
df[duplicated(df$a, df$b) | duplicated(df$a, df$b, fromLast = T), ]
# Description:df[,3] [5 × 3]
#
#
# a
# <dbl>
# b
# <dbl>
# c
# <dbl>
# 3 19 1981 3
# 4 19 1971 4
# 5 19 1981 5
# 8 32 1994 8
# 9 32 1999 9
# 5 rows
df %>%
group_by(a, b) %>%
summarise(a = a, b = b, c = c, n = n()) %>%
subset(n > 1) %>%
select(a, b, c)
#
# A tibble:2 x 3
# Groups:a, b [1]
# a
# <dbl>
# b
# <dbl>
# c
# <dbl>
# 19 1981 3
# 19 1981 5
# 2 rows
df[duplicated(df, incomparables = c(c)), ]
# Error: argument 'incomparables != FALSE' is not used (yet)
# This error occurs even with no libraries loaded.
我可能遗漏了 duplicated()
在括号中的使用方式,但我无法弄清楚。
另外,dplyr 返回一个 tibble,删除索引,这对你来说可能是一个缺点。
【讨论】:
【参考方案5】:我想出了一个使用嵌套 sapply 的解决方案:
> village_dups =
village[unique(unlist(which(sapply(sapply(village$Names,function(x)
which(village$Names==x)),function(y) length(y)) > 1))),]
> village_dups
Names age height
1 John 18 76.1
2 John 19 77.0
3 John 20 78.1
5 Paul 22 78.8
6 Paul 23 79.7
7 Paul 24 79.9
8 Khan 25 81.1
9 Khan 26 81.2
10 Khan 27 81.8
【讨论】:
以上是关于在 data.frame 中显示重复记录并省略单个记录的主要内容,如果未能解决你的问题,请参考以下文章
as.data.frame 将嵌套列表展平为单行,而不是为每条记录创建行 [重复]