> set.seed(2014)
> m<-matrix(sample(10,16,replace=TRUE),nrow=4)
> m
[,1] [,2] [,3] [,4]
[1,] 3 6 1 7
[2,] 2 1 2 6
[3,] 7 10 7 7
[4,] 4 7 1 5
对于每一行,我想检索该行中第一个元素的索引,该索引大于或等于最后一个元素,否则为NA。因此,对于第1行,前三列中没有元素&gt; = 7,因此应返回NA。对于第3行,第一个元素是> = 7,因此应该返回1。
结果应该是长度为4的矢量(NA,NA,1,2)
我认为解决方案可能涉及申请,但我无法弄清楚如何做到正确。另外,请记住效率,因为我的真实矩阵可能有数百万行。
由于
答案 0 :(得分:3)
这是一种可能性 - 虽然它可能会占用大量空间用于中期结果。
set.seed(2014)
m <- matrix(sample(10,16,replace=TRUE),nrow=4)
m2 <- sweep(m,1,m[,ncol(m)],">=")
v <- apply(m2,1,function(x) which(x)[1])
ifelse(v==ncol(m),NA,v)
基于Rcpp的解决方案只需要尽可能快地遍历每一行就会更快(如果有人写了一个通用的,快速的which.first()
函数会很好......
答案 1 :(得分:2)
另一次尝试:
apply(m[,-ncol(m)] >= m[,ncol(m)], 1, match, x=TRUE)
#[1] NA NA 1 2
或删除apply
:
chk <- m[,-ncol(m)] >= m[,ncol(m)]
replace(max.col(chk,"first"), rowSums(chk)==0, NA)
#[1] NA NA 1 2
它实际上创建了除最后一列之外的所有m
列的逻辑矩阵,测试值是否为>=
到最后一列值。然后使用TRUE
提取每行中第一个match
的位置。
使用比Ben解决方案更大的矩阵测试速度:
m<-matrix(sample(10,1.6e6,replace=TRUE),nrow=4e5)
replicate(5,
system.time(
apply(m[,-ncol(m)] >= m[,ncol(m)], 1, match, x=TRUE)
))
#elapsed 0.7 0.77 0.77 0.76 0.93
replicate(5,
system.time({
m2 <- sweep(m,1,m[,ncol(m)],">=")
v <- apply(m2,1,function(x) which(x)[1])
ifelse(v==ncol(m),NA,v)
}))
#elapsed 1.11 1.04 1.10 1.06 1.06
答案 2 :(得分:1)
这是一个简单的实现:
getFirst <- function(vec) {
temp = which(vec[1:(length(vec)-1)] >= vec[length(vec)])
if(length(temp) == 0) NA else temp[1]
}
index <- NULL
for(i in 1:nrow(m)){
index[i] <- getFirst(m[i,])
}
index
您也可以一步完成:
apply(m,1,function(vec) {
temp = which(vec[1:(length(vec)-1)] >= vec[length(vec)])
if(length(temp) == 0) NA else temp[1]
})