查找具有唯一值组合(R)的行

时间:2019-11-26 19:52:00

标签: r dataframe data.table

标题变得更复杂了,我敢肯定,如果我能想到一种更好地描述它的方法,我会用Google更好地描述它。

我有如下数据:

SET                     ID    
100301006              1287025
100301006              1287026
100301010              1287027
100301013              1287030
100301011              1287027

,我想识别并选择那些行中的每个值在该列中都具有唯一值的那些行。在上面的示例中,我只想抓取行:

100301013              1287030

我不希望SET 100301006,因为它与ID字段中的2个不同记录(12870251287026)匹配。同样,我也不想SET 100301010,因为它与(ID)匹配的1287027记录也可以匹配另一个SET(10030011)。

在某些情况下,可能有超过2个匹配项。

我可以循环执行此操作,但这似乎很简单。我很喜欢基本的R或data.table解决方案,但是我对dplyr不太感兴趣(试图使依赖性最小化)。

4 个答案:

答案 0 :(得分:3)

这是一个快速的base-R hack:

df <- read.table(header = TRUE, stringsAsFactors = FALSE, text = "
SET                     ID    
100301006              1287025
100301006              1287026
100301010              1287027
100301013              1287030
100301011              1287027")

counts <- sapply(df, function(x) { tb <- table(x); tb[ match(x, names(tb)) ]; })
counts
#           SET ID
# 100301006   2  1
# 100301006   2  1
# 100301010   1  2
# 100301013   1  1
# 100301011   1  2

在这一点上,我们具有在其列中找到每个元素的次数...,因此我们希望所有计数均为1的行。

df[ rowSums(counts == 1) == ncol(df), ]
#         SET      ID
# 4 100301013 1287030

答案 1 :(得分:3)

我们可以在每列上独立使用duplicated来创建逻辑list的{​​{1}},vectorReduce到单个向量并使用用来对数据集的行进行子集

&

或者按照@ chinsoon12的建议

df1[Reduce(`&`, lapply(df1, function(x) 
         !(duplicated(x)|duplicated(x, fromLast = TRUE)))),]
#     SET      ID
#4 100301013 1287030

数据

 m1 <- sapply(df1, function(x) !(duplicated(x)| duplicated(x, fromLast = TRUE)))
 df1[rowSums(m1) == ncol(m1),, drop = FALSE]

答案 2 :(得分:1)

使用base R,也许您可​​以使用ave()来做到:

r <-df[which(with(df,ave(seq(nrow(df)),SET,FUN = length)*ave(seq(nrow(df)),ID,FUN = length)) == 1),]
> r
        SET      ID
4 100301013 1287030

数据

df <- read.table(text="SET                     ID    
100301006              1287025
100301006              1287026
100301010              1287027
100301013              1287030
100301011              1287027",header = T)

答案 3 :(得分:1)

您可以使用data.table仅选择具有1行的组,首先按ID分组,然后按SET分组。这类似于@ r2evans方法,用于检查ID和SET的计数是否均为1。

library(data.table)
setDT(df)

df[, if(.N == 1) .SD, ID][, if(.N == 1) .SD, SET]

#          SET      ID
# 1: 100301013 1287030

或超过2列

Reduce(function(x, y) x[, if(.N == 1) .SD, y], names(df), init = df)
#         ID       SET
# 1: 1287030 100301013