2014-02-06 41 views
2

我与这些值的数据帧(建立在这样一种方式):选择行等多个列没有重复值

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 

如果我使用复制命令上的一列,然后其他的,我会丢弃想要的行。

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

与更多的行又如:

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出现一次都很好。

谢谢

雅各

+3

你如何决定是否1,10; 2,11保留或可以是1,11; 2,10? – Ananta

+0

在您的示例中,这两个值都显示两次。我不明白你的问题。也许只是简单地做“独特的(df)”的 – TomR

+0

。 –

回答

0

如果您知道数据被安排在你的榜样,骑自行车通过id2id1每个值,并以相同的顺序,解决办法很简单:

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 3行的矩阵。现在,检查重复值:

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,依此类推。我把这个循环作为读者的练习。