r - 其中(vector1 <vector2)

标签 r max simultaneous which

首先让我们举一个小例子,它以R计算:

x<- c(1,3,1,4,2)
max(which(x<2))
[1] 3

现在,我不仅要针对一个值2进行此操作,还要同时针对多个值进行此操作。它应该给我这样的东西:
max(which(x<c(1,2,3,4,5,6)))
[1] NA 3 5 5 5 5

当然,我可以运行for循环,但这很慢:
for(i in c(1,2,3,4,5,6)){    
test[i]<-max(which(x<i))
}

有快速的方法吗?

最佳答案

找到在x中看到的每个值的最大索引:

xvals    <- unique(x)
xmaxindx <- length(x) - match(xvals,rev(x)) + 1L

改编
xvals    <- xvals[order(xmaxindx,decreasing=TRUE)]
xmaxindx <- xmaxindx[order(xmaxindx,decreasing=TRUE)]   
# 2 4 1 3 
# 5 4 3 2

从以下选项中进行选择:
xmaxindx[vapply(1:6,function(z){
  ok <- xvals < z
  if(length(ok)) which(ok)[1] else NA_integer_
},integer(1))]
# <NA>    1    2    2    2    2 
#   NA    3    5    5    5    5 

它方便地报告值(第一行)和索引(第二行)。
sapply方法更简单,可能不会更慢:
xmaxindx[sapply(1:6,function(z) which(xvals < z)[1])]    

基准。 没有完全描述OP的情况,但是无论如何,这里有一些基准测试:
# setup
nicola <- function() max.col(outer(y,x,">"),ties.method="last")*NA^(y<=min(x))
frank  <- function(){
    xvals    <- unique(x)
    xmaxindx <- length(x) - match(xvals,rev(x)) + 1L

    xvals    <- xvals[order(xmaxindx,decreasing=TRUE)]
    xmaxindx <- xmaxindx[order(xmaxindx,decreasing=TRUE)]   
    xmaxindx[vapply(y,function(z){
      ok <- xvals < z
      if(length(ok)) which(ok)[1] else NA_integer_
    },integer(1))]
}
beauvel <- function() 
    Vectorize(function(u) ifelse(length(which(x<u))==0,NA,max(which(x<u))))(y)
davida <- function() vapply(y, function(i) c(max(which(x < i)),NA)[1], double(1))
hallo <- function(){
    test <- vector("integer",length(y))
    for(i in y){    
        test[i]<-max(which(x<i))
    }
    test
}
josho <- function(){
    xo <- sort(unique(x))
    xi <- cummax(1L + length(x) - match(xo, rev(x)))
    xi[cut(y, c(xo, Inf))]
}
require(microbenchmark)

(@MrHallo和@DavidArenburg的警告方式与我现在编写的方式类似,但可以解决。)以下是一些结果:
> x <- sample(1:4,1e6,replace=TRUE)
> y <- 1:6 
> microbenchmark(nicola(),frank(),beauvel(),davida(),hallo(),josho(),times=10)
Unit: milliseconds
      expr      min       lq     mean   median        uq       max neval
  nicola() 76.17992 78.01171 99.75596 98.43919 120.81776 127.63058    10
   frank() 25.27245 25.44666 36.41508 28.44055  45.32306  73.66652    10
 beauvel() 47.70081 59.47828 67.44918 68.93808  74.12869  95.20936    10
  davida() 26.52582 26.55827 33.93855 30.00990  35.55436  57.24119    10
   hallo() 26.58186 26.63984 32.68850 28.68163  33.54364  50.49190    10
   josho() 25.69634 26.28724 37.95341 30.50828  47.90526  68.30376    10
There were 20 warnings (use warnings() to see them)
>  
> 
> x <- sample(1:80,1e6,replace=TRUE)
> y <- 1:60
> microbenchmark(nicola(),frank(),beauvel(),davida(),hallo(),josho(),times=10)
Unit: milliseconds
      expr        min         lq       mean     median         uq       max neval
  nicola() 2341.96795 2395.68816 2446.60612 2481.14602 2496.77128 2504.8117    10
   frank()   25.67026   25.81119   42.80353   30.41979   53.19950  123.7467    10
 beauvel()  665.26904  686.63822  728.48755  734.04857  753.69499  784.7280    10
  davida()  326.79072  359.22803  390.66077  397.50163  420.66266  456.8318    10
   hallo()  330.10586  349.40995  380.33538  389.71356  397.76407  443.0808    10
   josho()   26.06863   30.76836   35.04775   31.05701   38.84259   57.3946    10
There were 20 warnings (use warnings() to see them)
>  
> 
> x <- sample(sample(1e5,1e1),1e6,replace=TRUE)
> y <- sample(1e5,1e4)
> microbenchmark(frank(),josho(),times=10)
Unit: milliseconds
    expr      min       lq     mean   median       uq       max neval
 frank() 69.41371 74.53816 94.41251 89.53743 107.6402 134.01839    10
 josho() 35.70584 37.37200 56.42519 54.13120  63.3452  90.42475    10

当然,对于OP的真实情况,比较结果可能会有所不同。

关于r - 其中(vector1 <vector2),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30170400/

相关文章:

R:名称相同时在行中求和值

r - 使用 lm()、nls()(和 glm()?)估计马尔萨斯增长模型中的人口增长率

用于保留大小写模式、大写的正则表达式

FFMPEG:创建一个视频,该视频具有 n 输入视频的每个像素的最大值

MySQL - 特定日期发生最多的事件?

r - 如何使用ggplot设置单行的颜色

algorithm - Max Flow 线性时间算法,找到一个有效的流

ios - Pan 和 2 Finger Pinch 同时 iOS - 同时 -

c - 在 C 中更多地了解 pthreads

python - 用 Python 求解联立方程