我正在尝试编写一些代码以在庞大的向量数组中找到特定的向量,并返回该向量的副本出现位置的索引。在尝试调试时,我试图学习all.equal
的行为(建议here,identical
似乎由于类型不匹配而被排除)。我现在编写了以下代码:
data<-replicate(100000,sample(4))
which( apply(data, 2, function(x) all.equal(c(1:4),data)) == TRUE)
据我所知,我写的第一行会生成从1到4的整数的大量排列,第二行会搜索它们的确切排列1、2、3、4的任何情况。从统计学上讲,我非常有信心此排列应该出现在此列表的某个位置,在我的特殊情况下,它是第九个条目。但是,每次我运行此代码或其上的任何变体时,都被告知永远不会出现所需的排列。
我做错了什么?坦率地说,当我不得不查找如何在向量列表中查找向量时,我开始怀疑自己犯了一个重大错误,并且不得不使用两个函数来这样做。有没有更简单的方法?
实际上,您几乎在那里,这只是一个小错字。正确的代码是
which(apply(data, 2, function(x) all.equal(x, c(1, 2, 3, 4))) == TRUE)
因为您需要提供数据进行比较,而必要的数据是列而不是整个数据集。这样做的方法将永远不会找到匹配项,因为整个数组将永远不会匹配一个向量。
尝试以下方法:
which( apply(data, 2, function(x) all.equal(c(1:4),x)) == TRUE)
不同之处在于,您在代码中将data
的整个结构与1:4进行了比较,因为大小不匹配,因此永远不会是TRUE
。我在要应用的函数内部用data
替换了x
,因此现在将每一列与1:4进行比较。
您的代码中也有一些冗余,c(1:4)
与1:4
相同。在这种情况下,all.equal
可能是过大的,因为它所做的不只是比较(它与模糊因素进行比较,并告诉您情况有何不同)。您使用它的方式是将TRUE
转换为字符。不提前简化会更有效。这是一个快速比较(较小的模拟数据):
> library(microbenchmark)
>
> microbenchmark(
+ ae = {
+ data<-replicate(100,sample(4))
+ which( apply(data, 2, function(x) all.equal(c(1:4),x)) == TRUE)
+ },
+ e = {
+ data <- replicate(100, sample(4), simplify=FALSE)
+ which(sapply(data, function(x)all(x==(1:4))))
+ }
+ )
Unit: microseconds
expr min lq mean median uq max neval cld
ae 4063.205 4303.3370 4940.2126 4501.5080 4951.623 10953.339 100 b
e 455.934 493.3115 578.4828 523.4605 562.601 2013.444 100 a
简化的代码平均大约需要运行时间的九分之一。