我想将数据框子集化为仅包含具有三列唯一组合的行。我的情况类似于this问题中提到的情况,但我还想保留数据中的其他列。这是我的例子:
> df
v1 v2 v3 v4 v5
1 7 1 A 100 98
2 7 2 A 98 97
3 8 1 C NA 80
4 8 1 C 78 75
5 8 1 C 50 62
6 9 3 C 75 75
请求的输出将是这样的,我正在寻找基于v1,v2和v3的唯一案例:
> df.new
v1 v2 v3 v4 v5
1 7 1 A 100 98
2 7 2 A 98 97
3 8 1 C NA 80
6 9 3 C 75 75
如果我能恢复非常独特的行,那也很棒:
> df.dupes
v1 v2 v3 v4 v5
3 8 1 C NA 80
4 8 1 C 78 75
5 8 1 C 50 62
我在sql(here)中看到了一个相关的问题,但我无法在R中得到这个。我确信这很简单,但却遇到了unique()和subset()hasn没有成果。提前谢谢。
答案 0 :(得分:53)
您可以使用duplicated()
功能查找唯一组合:
> df[!duplicated(df[1:3]),]
v1 v2 v3 v4 v5
1 7 1 A 100 98
2 7 2 A 98 97
3 8 1 C NA 80
6 9 3 C 75 75
要仅获取重复项,您可以在两个方向上进行检查:
> df[duplicated(df[1:3]) | duplicated(df[1:3], fromLast=TRUE),]
v1 v2 v3 v4 v5
3 8 1 C NA 80
4 8 1 C 78 75
5 8 1 C 50 62
答案 1 :(得分:4)
您可以使用plyr
包:
library(plyr)
ddply(df, c("v1","v2","v3"), head, 1)
# v1 v2 v3 v4 v5
# 1 7 1 A 100 98
# 2 7 2 A 98 97
# 3 8 1 C NA 80
# 4 9 3 C 75 75
ddply(df, c("v1","v2","v3"), function(x) if(nrow(x)>1) x else NULL)
# v1 v2 v3 v4 v5
# 1 8 1 C NA 80
# 2 8 1 C 78 75
# 3 8 1 C 50 62
答案 2 :(得分:4)
使用dplyr
即可:
library(dplyr)
# distinct
df %>%
distinct(v1, v2, v3, .keep_all = T)
# non-distinct only
df %>%
group_by(v1, v2, v3) %>%
filter(n() > 1)
# exclude any non-distinct
df %>%
group_by(v1, v2, v3) %>%
filter(n() == 1)
答案 3 :(得分:2)
是的,但是如果您有太多数据,使用plyr和ddply非常慢。
你试试这种事情:df[ cbind( which(duplicated(df[1:3])), which(duplicated(df[1:3], fromLast=TRUE))),]
或::
from = which(duplicated(df[1:3])
to = which(duplicated(df[1:3], fromLast=TRUE))
df[cbind(from,to),]
大多数人都会更快。
测试一下,让我们知道
有一些错误,但我猜你可以解决这些错误,只要你明白了。
也尝试独特和所有
答案 4 :(得分:1)
一种非优雅但功能性的方法是将给定行的条目粘贴在一起,找到哪些是唯一(或非唯一)行,如:
df.vector=apply(df,1,FUN=function(x) {paste(x,collapse="")})
df.table=table(df.vector)
然后用以下内容获取重复项的索引:
which(df.vector%in%names(which(df.table>1)))
答案 5 :(得分:0)
我知道这是一个非常老的问题,但是无论如何,使用unique()函数的显而易见的解决方案也应该在此处显示:
unique(df[1:3])
或通过名称指定列:
unique(df[c("v1","v2","v3)]
...并指定行:
unique(df[,c("v1","v2","v3)]
答案 6 :(得分:0)
假设您正在使用data.table,就一个或多个变量而言,具有独特的情况很容易。语法如下所示
unique(DT, by = "var1, var2")