R,为每个唯一对选择第一个数据帧行,忽略顺序

时间:2016-07-31 19:13:27

标签: r

围绕这个问题调情有很多问题,但我无法找到对我特别关注的答案。我有一个具有这种通用格式的数据框。

dat <- data.frame(V1 = c(1,1,2,1,2,4,5), V2 = c(1,2,1,2,1,5,4), V3 =    c('date1','date1','date2','date3','date4','date1','date2'))

dat
V1 V2    V3
1  1 date1
2  1 date1
1  2 date2
1  2 date3
2  1 date4
5  4 date1
4  5 date2

我想找到第1列和第2列中的唯一对(因此第2,3,4,5行全部合并为一个唯一对),无论顺序如何(1,2 = 2,1)。我在SO(Unique pairs in R, ignoring order

上找到了这个很好的代码
colwise <- function(dat) data.frame(unique(cbind(pmin(dat[,1], dat[,2]), pmax(dat[,1], dat[,2]))))

这对于提取第1列和第2列非常有用。

colwise(dat)
V1 V2
1  1
1  2
4  5

但是,我想找到唯一的对(如上所述),但也包括每个唯一对的原始数据集的整个第一行。在上面的例子中,最终输出将是

dat
V1 V2    V3
1  1 date1
1  2 date1
4  5 date1

在我的实际数据集中,我有更多列和几百万行,但只有100-200个真正独特的第1列和第2列组合。此外,唯一对列实际上不是我数据集中的第1,2列指定特定列以测试唯一性的能力非常重要。

有没有人对如何修改colwise函数或如何使用生成的唯一对集合从原始数据框中提取基于该唯一对的第一整行有一些好的想法?

谢谢

3 个答案:

答案 0 :(得分:4)

dplyr包中的distinct函数执行此操作。要忽略订单,您可以先定义smallerlarger列,然后删除这些列:

library(dplyr)
dat %>%
  distinct(smaller = pmin(V1, V2),
           larger = pmax(V1, V2),
           .keep_all = TRUE) %>%
  select(-smaller, -larger)

.keep_all参数(因为dplyr 0.5)告诉它不要丢弃其他(非V1 / V2)列。

答案 1 :(得分:2)

使用duplicated代替unique获取唯一对的重复索引而不是唯一对,然后删除重复项:

dat <- data.frame(V1 = c(1,1,2,1,2,4,5), V2 = c(1,2,1,2,1,5,4), V3 = c('date1','date1','date2','date3','date4','date1','date2'))

dup <- function(dat) duplicated(cbind(pmin(dat[,1], dat[,2]), pmax(dat[,1], dat[,2])))

print(dat[!dup(dat),])
##  V1 V2    V3
##1  1  1 date1
##2  1  2 date1
##6  4  5 date1

请注意,这只会为您提供第一个重复唯一对的整行,并且您说这就是您想要的。

希望这有帮助。

答案 2 :(得分:0)

您可以先对列进行排序,然后使用duplicated

dat <- transform(dat, V1a=pmin(V1,V2), V2a=pmax(V1,V2))
idx <- which(!duplicated(dat[,c("V1a", "V2a")]))
dat <- dat[idx,]