测试矩阵或数据帧的行是否按R排序
测试矩阵中的行是否已排序的有效方法是什么?[更新:见Aaron的Rcpp答案-简单且快速。] 我正在移植一些使用的代码。似乎测试矩阵或数据帧的行是否按R排序,r,sorting,matlab,R,Sorting,Matlab,测试矩阵中的行是否已排序的有效方法是什么?[更新:见Aaron的Rcpp答案-简单且快速。] 我正在移植一些使用的代码。似乎是。未排序的并没有超出向量的范围,我正在写或寻找其他东西。简单的方法是检查矩阵(或数据帧)的排序版本是否与原始版本相同,但这显然是低效的 注意:对于排序,la,我的代码基本上使用了SortedDF嗯,蛮力方法是循环和比较,一旦发现违规就中止 这种方法可以在R中容易地实现和测试,然后被传递到一个简单的C++函数,我们可以连接到R VIN和(或者如果必须的话,C),因为循环是从
是。未排序的
并没有超出向量的范围,我正在写或寻找其他东西。简单的方法是检查矩阵(或数据帧)的排序版本是否与原始版本相同,但这显然是低效的
注意:对于排序,la,我的代码基本上使用了
SortedDF嗯,蛮力方法是循环和比较,一旦发现违规就中止
这种方法可以在R中容易地实现和测试,然后被传递到一个简单的C++函数,我们可以连接到R VIN和(或者如果必须的话,C),因为循环是从编译语言的实现中获益的。
否则,您不能使用类似于diff()
的方法检查所有增量是否为非负吗?如果y已排序,则执行。调用(顺序,y)返回1:nrow(y)
请注意,这不会比较矩阵,但它不会在发现不匹配项时立即显示出来。那么,为什么不使用:
all(do.call(order, y)==seq(nrow(y)))
这样可以避免创建有序矩阵,并确保它检查您的排序方式。您可以使用do.call
语句和is.unsorted
:
issorted.matrix <- function(A) {!is.unsorted(do.call("order",data.frame(A)))}
issorted.matrix更新:我决定可以使用Rcpp实践
library(Rcpp)
library(inline)
isRowSorted <- cxxfunction(signature(A="numeric"), body='
Rcpp::NumericMatrix Am(A);
for(int i = 1; i < Am.nrow(); i++) {
for(int j = 0; j < Am.ncol(); j++) {
if( Am(i-1,j) < Am(i,j) ) { break; }
if( Am(i-1,j) > Am(i,j) ) { return(wrap(false)); }
}
}
return(wrap(true));
', plugin="Rcpp")
rownames(y) <- NULL # because as.matrix is faster without rownames
isRowSorted(as.matrix(y))
库(Rcpp)
库(内联)
isRowSorted+1,但我鼓励您在Windows上使用vim用普通C编写它不,diff()
不太管用。:)用上面的例子试试:diff(as.matrix(y))
。出现了一些负值;所以,我们可以做的是确保每个差分行的正值总是在负值之前。我怀疑这样做仍然不雅观。Josh,真正的C程序员只使用ed之类的行编辑器。或者你可以像Barry和Nick所展示的那样直接在R中做一些聪明的事情。在进一步的测试表明替代方法涉及排序之后,似乎有必要进行迭代,在这种情况下,Rcpp似乎很有希望。+1这很有希望。我忽略了数据帧中非数字值的seq
问题,这就是order
的作用。现在我明白了当出现不匹配时不向外倾斜的意思。因此,它是简洁的,但仍然是排序。“迭代器:它们会使它慢多少取决于矩阵的性质;它正在处理来自rle
的结果,因此,如果类别很少(比如在您的示例中,有三个),那么它看起来相当快;如果有很多类别,我希望它会大大放缓。这太棒了。速度非常快,使用行名
的技巧非常聪明。我本想给Rcpp一次机会,但我猜不到行名
的加速。对使用此命令的其他人的一个建议是:isS4
(大写S)是一个base R命令。小心点,看起来不错!我会使用bool out
而不是LogicalVector(1)
,然后使用return(wrap(out))
返回。附录:如果对象已经是一个矩阵(即,在计时之外执行行名
和as.matrix
),则执行速度非常快。我可能需要学习microbenchmark
:)现在使用wrap
,并已重命名为isRowSorted
。
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10
1 3 1 2 2 3 1 3 3 2 2
2 1 1 1 3 2 3 2 3 3 2
3 3 3 1 2 1 1 2 1 2 3
testSorted = function(y){all(do.call(order,y)==1:nrow(y))}
all(do.call(order, y)==seq(nrow(y)))
issorted.matrix <- function(A) {!is.unsorted(do.call("order",data.frame(A)))}
library(Rcpp)
library(inline)
isRowSorted <- cxxfunction(signature(A="numeric"), body='
Rcpp::NumericMatrix Am(A);
for(int i = 1; i < Am.nrow(); i++) {
for(int j = 0; j < Am.ncol(); j++) {
if( Am(i-1,j) < Am(i,j) ) { break; }
if( Am(i-1,j) > Am(i,j) ) { return(wrap(false)); }
}
}
return(wrap(true));
', plugin="Rcpp")
rownames(y) <- NULL # because as.matrix is faster without rownames
isRowSorted(as.matrix(y))
iss3 <- function(x) {
x2 <- sign(do.call(cbind, lapply(x, diff)))
x3 <- t(x2)*(2^((ncol(x)-1):0))
all(colSums(x3)>=0)
}
iss2 <- function(y) {
b <- c(0,nrow(y))
for(i in 1:ncol(y)) {
z <- rle(y[,i])
b2 <- cumsum(z$lengths)
sp <- split(z$values, cut(b2, breaks=b))
for(spi in sp) {
if(is.unsorted(spi)) return(FALSE)
}
b <- c(0, b2)
}
return(TRUE)
}