2015-01-12 78 views
17

我想檢查兩個向量是否包含相同的元素,即使它們的排序不相同。例如,該功能(讓我們稱之爲SameElements)應該滿足下列條件:檢查兩個向量是否包含相同(無序)的元素R

SameElements(c(1, 2, 3), c(1, 2, 3)) # TRUE 
SameElements(c(1, 2, 3), c(3, 2, 1)) # TRUE 
SameElements(c(1, 2, 1), c(1, 2)) # FALSE 
SameElements(c(1, 1, 2, 3), c(3, 2, 1)) # FALSE 

編輯1:指定函數應該返回F如果載體包含相同的元素,但具有不同的頻率。

編輯2:清理問題以省略初始答案,因爲現在在我的實際答案中。

+0

如何'所有(一個在%B%)'。它基本上回答了問題*矢量'b'中是否包含'a'的所有元素?*如果這些值是唯一的,那麼您也可以使用'anyNA(match(a,b))' –

+0

,對不起,在這裏不清楚。我在這種情況下尋找F(爲了清晰起見編輯的問題)。 –

回答

8

代替的清潔替代的,這裏的已知的解決方案:每nrussell的建議identical,而不是all.equal(...) == T

SameElements <- function(a, b) return(identical(sort(a), sort(b))) 
SameElements(c(1, 2, 3), c(1, 3, 2)) # TRUE 
SameElements(c(1, 2, 3), c(1, 1, 3, 2)) # FALSE 

編輯。

+1

分裂毛髮的種類,但'F < - 函數(a,b)相同(sort ),sort(b))''會從上面的'SameElements'函數中爲你節省3個擊鍵('== T') - 整齊的問題,儘管+1。 – nrussell

+0

謝謝@nrussell,更新 –

30

我認爲你可以使用setequal(a,b)

更新更新setequal檢查,如果兩個向量由相同的元素,但它不檢查,如果這些元素在每個矢量相同的事件。

+2

setequal對我來說是新的,看起來整潔。 +1 –

+1

它基本上只是'%in%':) –

+1

雅算出來了。另外它應該做更多的事情,因爲它比較慢。但是,作爲一個「更清潔的替代品」它贏了。很難得到任何清潔劑。 :) –

3

您可能會對「比較」軟件包感興趣。這個答案演示了compare()函數,但是對於您的情況,您可能會在compareIgnoreOrder()(它幾乎與您的問題標題完全匹配)時做得很好。

有幾個參數可以作爲轉換添加,應該允許在嘗試比較元素時使用這些參數。在下面的例子中(爲了節省一些輸入),我要求函數允許所有的變換(allowAll = TRUE),除了改變向量長度(shorten = FALSE)。

library(compare) 
compare(A1, A2, allowAll = TRUE, shorten = FALSE) 
# TRUE 
compare(A1, A3, allowAll = TRUE, shorten = FALSE) 
# TRUE 
# sorted 
compare(A1, A4, allowAll = TRUE, shorten = FALSE) 
# FALSE 
# sorted 
compare(B1, B2, allowAll = TRUE, shorten = FALSE) 
# FALSE 
# sorted 
compare(B1, A4, allowAll = TRUE, shorten = FALSE) 
# FALSE 
# sorted 
compare(A3f, A1, allowAll = TRUE, shorten = FALSE) 
# TRUE 
# coerced from <numeric> to <factor> 
# sorted 

的樣本數據:

A1 <- c(1, 2, 3); A2 <- c(1, 2, 3) 
A3 <- c(3, 2, 1); A4 <- c(1, 1, 2, 3) 
B1 <- c(1, 2, 1); B2 <- c(1, 2) 
A3f <- factor(A3) 
0

這裏是我的解決方案:

SameElements <- function (a,b){ 
    l <- Map(table,list(a, b)) # Compute frequencies - returns ordered table 
    Reduce(identical,l) # Check if frequencies are the same for all input vectors 
} 

SameElements(c(1, 2, 3), c(1, 2, 3)) # TRUE 
SameElements(c(1, 2, 3), c(3, 2, 1)) # TRUE 
SameElements(c(1, 2, 1), c(1, 2)) # FALSE 
SameElements(c(1, 1, 2, 3), c(3, 2, 1)) # FALSE 

正如你可以看到它適用於任何數量的輸入向量的,只要你把它們放在一個名單。

一個內膽:

Reduce(identical,Map(table,listOfVectors)) 
相關問題