选择行,使多列没有重复的值

时间:2014-02-06 18:08:26

标签: r dataframe unique duplicate-removal

我有一个包含这些值的数据框(以这种方式构建):

id1 = (c(1,1,2,2))
id2 = (c(10,11,10,11))
value =c(50,50,50,50)
df = data.frame(id1,id2,value)

df : 
  value id1 id2
1    50   1  10
2    50   1  11
3    50   2  10
4    50   2  11

我想只保留id1和id2都是唯一的行(id1和id2的每个值只能出现一次),每个id可能还有一个副本:

df_unique : 
value id1 id2
1    50   1  10
4    50   2  11

如果我在其中一列上使用重复命令然后另一列,我会丢弃想要的行。

只要每个元素在中,返回(1,11)和(2,10)的解决方案也是好的 id1和id2是唯一的。

另一个包含更多行的示例:

id1 = (c(1,1,1,2,2,2,3,3,3))
id2 = (c(10,11,12,10,11,12,10,11,12))
value =rep(50,9)
df = data.frame(id1,id2,value)

df:
  id1 id2 value
1   1  10    50
2   1  11    50
3   1  12    50
4   2  10    50
5   2  11    50
6   2  12    50
7   3  10    50
8   3  11    50
9   3  12    50

好的答案是:(1,10),(2,11),(3,12),还有id1和id2出现一次的任何其他答案都是好的。

谢谢,

雅各

1 个答案:

答案 0 :(得分:0)

如果您知道数据按照示例中的顺序进行排列,则为id2的每个值循环id1并按相同的顺序,解决方案很简单:

N <- 3 # Number of rows in the result
idx <- seq(1, N*N, by=N) + seq(0,to=N-1)
df[idx,]
##   id1 id2 value
## 1   1  10    50
## 5   2  11    50
## 9   3  12    50

我怀疑这是你要问的。如果行处于未知顺序或不是所有值都存在于另一列中的每个值的一列中,则必须检查N行的每个组合。

# Maximum number of result rows
N <- with(df, min(length(unique(id1)), length(unique(id2))))
N
## [1] 3

# Potential indices
index <- combn(seq(nrow(df)), N)

index是一个矩阵,其中每列代表df中的三行。现在检查重复值:

good <- apply(index, 2, function(x) !any(duplicated(df[x,'id1']) | duplicated(df[x,'id2'])))
对于通过测试的行组合,

good的值为TRUE

which(good)
## [1] 22 24 39 44 53 56
index[, good]
##      [,1] [,2] [,3] [,4] [,5] [,6]
## [1,]    1    1    2    2    3    3
## [2,]    5    6    4    6    4    5
## [3,]    9    8    9    7    8    7

上述矩阵的每一列代表通过测试的行的组合。

找到所有组合。您可能只想查找第一个组合,以便在找到匹配后不再继续测试其他组合。然后for是合适的:

for (i in seq(ncol(index))) {
  x <- index[,i]
  if (!any(duplicated(df[x,'id1']) | duplicated(df[x,'id2']))) {
    rows <- x
    break
  }
}

df[rows,]
##   id1 id2 value
## 1   1  10    50
## 5   2  11    50
## 9   3  12    50

注意:根据数据,有可能使用N=3,您将不会获得通过测试的行。在这种情况下,请使用N=2重复此过程,依此类推。我将这个循环作为练习留给读者。