2014-02-06 62 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,依此類推。我把這個循環作爲讀者的練習。