检查两个向量是否包含 R 中的相同(无序)元素
Check whether two vectors contain the same (unordered) elements in R
我想检查两个向量是否包含相同的元素,即使它们的顺序不同。例如,函数(我们称它为 SameElements
)应满足以下条件:
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:指定当向量包含相同元素但频率不同时函数应 return F。
编辑 2:清理问题以省略初始答案,因为这是我现在的实际答案。
我想你可以使用 setequal(a,b)
Updated update setequal
检查两个向量是否由相同的元素组成,但不检查这些元素在每个向量中是否有相同的出现。
代替更清洁的替代方案,这是已知的解决方案:
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
编辑:根据 nrussell 的建议 identical
而不是 all.equal(...) == T
。
您可能对 "compare" 软件包感兴趣。 This answer demonstrates the compare()
function,但对于你的情况,你可能会用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)
这是我的解决方案:
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))
基本上你的问题可以概括为这些步骤:
if not same unique values: return FALSE
else if same Frequencies: return TRUE
else return True
在正确的 R 代码中:
SameElements = function(v1, v2)
{
tab1 = table(v1) ; tab2 = table(v2)
if( !all(names(tab1) == names(tab2)) ) return(FALSE) # Same unique values test
return(all(tab1==tab2)) # Same frequencies test
}
一些例子:
v1 = c(1, 2, 3)
v2 = c(3, 2, 1)
SameElements(v1, v2) # TRUE as both uniqueness and frequencies test are verified
v1 = c(1,1, 2,3)
v2 =c(3,2,1)
S
ameElements(v1, v2) # FALSE 因为违反了频率测试
PS : i) 您可以将 !all()
替换为 any()
~~~ii) 为了加快代码速度,当两个向量不
时,你可以快速 return FALSE
~~~具有相同的长度,从而避免频率计算。
我想检查两个向量是否包含相同的元素,即使它们的顺序不同。例如,函数(我们称它为 SameElements
)应满足以下条件:
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:指定当向量包含相同元素但频率不同时函数应 return F。
编辑 2:清理问题以省略初始答案,因为这是我现在的实际答案。
我想你可以使用 setequal(a,b)
Updated update setequal
检查两个向量是否由相同的元素组成,但不检查这些元素在每个向量中是否有相同的出现。
代替更清洁的替代方案,这是已知的解决方案:
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
编辑:根据 nrussell 的建议 identical
而不是 all.equal(...) == T
。
您可能对 "compare" 软件包感兴趣。 This answer demonstrates the compare()
function,但对于你的情况,你可能会用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)
这是我的解决方案:
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))
基本上你的问题可以概括为这些步骤:
if not same unique values: return FALSE
else if same Frequencies: return TRUE
else return True
在正确的 R 代码中:
SameElements = function(v1, v2)
{
tab1 = table(v1) ; tab2 = table(v2)
if( !all(names(tab1) == names(tab2)) ) return(FALSE) # Same unique values test
return(all(tab1==tab2)) # Same frequencies test
}
一些例子:
v1 = c(1, 2, 3)
v2 = c(3, 2, 1)
SameElements(v1, v2) # TRUE as both uniqueness and frequencies test are verified
v1 = c(1,1, 2,3)
v2 =c(3,2,1)
S
ameElements(v1, v2) # FALSE 因为违反了频率测试
PS : i) 您可以将 !all()
替换为 any()
~~~ii) 为了加快代码速度,当两个向量不
时,你可以快速 return FALSE
~~~具有相同的长度,从而避免频率计算。