r - 测试一个向量是否是另一个向量的最有效的方法
问题描述
我目前的解决方案是测试一个向量是否包含与另一个向量相同的值,而不管顺序如何
test_perm <- function(a, b) identical(sort(a), sort(b))
test_perm(1:4, 4:1) # TRUE
test_perm(1:4, 1:4) # TRUE
test_perm(1:4, 1:5) # FALSE
test_perm(4:1, 4:1) # TRUE
被迫排序a
和b
首先感觉有点不对,所以我想知道规范的方式是什么,即R
如果我最关心速度,推荐的方式是什么?
(感谢@sindri 的评论小更新)
解决方案
这里有两种策略,包benchmark()
中的函数提供了基准数据rbenchmark
。
# Your strategy using identical(). Note that I sort a and b in case a is not ordered.
set.seed(123)
a <- sample(1:1000, 100, replace = FALSE)
b <- sample(1:1000, 100, replace = FALSE)
identical(sort(a), sort(b))
> FALSE
# using anti_join() from dplyr. Anti-join returns the rows in a that are not in b.
library(dplyr)
set.seed(123)
a <- sample(1:1000, 100, replace = FALSE)
b <- sample(1:1000, 100, replace = FALSE)
diff <- anti_join(data.frame(a), data.frame(b), by = c("a" = "b"))
nrow(diff) == 0 # if all rows in a are in b, diff should have zero rows
> FALSE
现在这里是基准数据:
library(rbenchmark)
set.seed(123)
a <- sample(1:1000, 100)
b <- sample(1:1000, 100)
benchmark(
"sort_identical" = {
identical(sort(a), sort(b))
},
"anti_join" = {
require(dplyr)
diff <- anti_join(data.frame(a), data.frame(b), by = c("a" = "b"))
nrow(diff) == 0
},
replications = 1000,
columns = c("test", "replications", "elapsed",
"relative", "user.self", "sys.self")
)
test replications elapsed relative user.self sys.self
2 anti_join 1000 2.47 22.455 2.41 0
1 sort_identical 1000 0.11 1.000 0.11 0
实际的基准测试数据将取决于您的系统资源,但identical()
与我的其他想法相比,您在排序后使用的方法非常快anti_join()
。希望您也可以从这个答案中得出结论,您可以自己测试代码的速度。我碰巧喜欢这个rbenchmark
包裹,但这个microbenchmark
包裹也很好。
因为它是一个通用的基本 R 函数,所以我们可以期待sort()
它的表现非常好。但是,如果您阅读排序的帮助文件,您会发现它实际上使用内部通用原始函数xtfrm()
对数值数据进行排序。如果你能保证你的数据是数字的,你可以通过xtfrm()
直接调用来提高速度。xtfrm()
其他类型的数据可能会更慢。
set.seed(123)
a <- sample(1:1000, 100)
b <- sample(1:1000, 100)
benchmark(
"sort" = {
identical(sort(a), sort(b))
},
"xtfrm" = {
identical(xtfrm(a), xtfrm(b))
},
replications = 1000,
columns = c("test", "replications", "elapsed",
"relative", "user.self", "sys.self")
)
test replications elapsed relative user.self sys.self
1 sort 1000 0.11 11 0.10 0
2 xtfrm 1000 0.01 1 0.01 0
推荐阅读
- python - 为什么我的班级的 init 函数没有运行?
- yaml - 有没有办法检索 YAML 属性的子字符串?
- sql - drush sql-dump整个数据库,但只复制模式而不是一个表的数据
- javascript - 我正在做 LWC Superbadge 第 6 步。无法检索描述符的元数据是我不断收到的错误
- javascript - Node.JS MongoDB SyntaxError:无效或意外的令牌
- javascript - 通过 Ribbon Workbench 自定义按钮将 CRM 参数传递给 Javascript 函数以获取属性值
- sql-server - 在 Power BI 中使用实时连接,但也能够编辑数据和创建列/表
- android - 如何将视图模型绑定到 bottomsheetdialogfragment 和 @bindingadapter
- swift - 在 UIStackView 中的 UIButtons 之间添加空间的最佳方法是什么
- javascript - React:使用计算的属性名称更新状态