有没有办法找到向量中最后一个元素的索引,该向量在R中有一个实际值(即不是N/a)

有没有办法找到向量中最后一个元素的索引,该向量在R中有一个实际值(即不是N/a),r,na,R,Na,这是我的向量 x <- c("1", "1", "PNP004", "10", "10", NA, NA) xInd使用dplyr: dplyr::last(which(!is.na(yourvec))) 您可以从查找的结果中使用tail!是向量的.na tail(which(!is.na(x)), 1) #[1] 5 或者一个for循环 idxLNNA <- function

这是我的向量

x <- c("1", "1", "PNP004", "10", "10", NA,  NA)

x
Ind使用
dplyr

dplyr::last(which(!is.na(yourvec)))

您可以从查找
结果中使用
tail
!是向量的.na

tail(which(!is.na(x)), 1)
#[1] 5
或者一个for循环

idxLNNA <- function(x) {
  if(length(x) > 0) {
    for(i in length(x):1) if(!is.na(x[i])) break
    if(i == 1 & is.na(x[i])) {0} else {i}
  } else {0}
}
idxLNNA(x)
#[1] 5
或者从
x
length
中减去
rev
命中

length(x) - which.min(rev(is.na(x))) + 1 #Will fail in case on only NA
#length(x) - match(FALSE, is.na(rev(x))) + 1 #Alternative
#[1] 5
基准:

library(microbenchmark)

fun <- alist(Dason = max(which(!is.na(x)))
           , juljo = dplyr::last(which(!is.na(x)))
           , GKiTail = tail(which(!is.na(x)), 1)
           , GKiCum = which.max(cumsum(!is.na(x)))
           , GKiRev = length(x) - which.min(rev(is.na(x))) + 1
           , GKiMatch = length(x) - match(FALSE, is.na(rev(x))) + 1
           , GKiFor = idxLNNA(x)
             )

x <- numeric(1e6)
microbenchmark(list = fun, control=list(order="block"))
#Unit: microseconds
#     expr      min        lq       mean    median       uq        max neval cld
#    Dason 4855.744 5740.1355 7941.21809 7082.5535 7671.371 107165.201   100  bc
#    juljo 4145.322 4616.7815 5756.38147 6134.9200 6625.008   7378.724   100  b 
#  GKiTail 4082.716 4434.3880 5576.70509 6051.1465 6489.966   7433.579   100  b 
#   GKiCum 6552.213 7445.1525 8632.12253 8988.8700 9420.481  16791.845   100   c
#   GKiRev 4005.929 4138.4735 5845.70457 4212.7470 5851.034 101665.685   100  b 
# GKiMatch 5180.600 5483.8545 7507.82723 5998.2760 7373.458 108327.967   100  bc
#   GKiFor    1.541    1.5775    2.16462    1.6145    1.724     20.436   100 a  

x <- rep(NA, 1e6) #Dason, GKiCum and GKiRev Fail
microbenchmark(list = fun[-c(1,4,5)], control=list(order="block"))
#Unit: milliseconds
#     expr        min         lq       mean     median         uq        max neval cld
#    juljo   3.011272   3.076340   3.525396   3.111676   3.494768   6.367839   100 a  
#  GKiTail   2.942336   3.014327   3.529691   3.063891   3.809653   6.136984   100 a  
# GKiMatch   4.928626   4.975369   7.490588   5.039941   6.823780  98.194653   100  b 
#   GKiFor 155.078444 159.314918 163.706542 160.168266 163.464146 258.136977   100   c

x <- numeric(0) #Dason Fails
microbenchmark(list = fun[-1], control=list(order="block"))
Unit: nanoseconds
#     expr   min      lq     mean  median      uq    max neval  cld
#    juljo 26794 27324.0 28694.75 27640.0 27933.0 120143   100    d
#  GKiTail  6746  7027.5  7396.45  7206.5  7432.5  21898   100   c 
#   GKiCum   869   880.0   947.72   890.0   948.0   3403   100 a   
#   GKiRev  2466  2527.0  2657.99  2565.5  2652.0   8071   100  b  
# GKiMatch  2739  2807.5  2919.78  2862.5  2935.5   5651   100  b  
#   GKiFor   492   512.5   671.74   537.5   604.5   9088   100 a   
库(微基准)

有趣的可能是
tail(哪一个(!is.na(x)),1)
@GKi为什么不发布一个答案?这可能对将来的其他人有用。谢谢!作品great@Dason谢谢我补充说,如果只有NA,则
cumsum
将失败(返回1)。
length(x) - which.min(rev(is.na(x))) + 1 #Will fail in case on only NA
#length(x) - match(FALSE, is.na(rev(x))) + 1 #Alternative
#[1] 5
library(microbenchmark)

fun <- alist(Dason = max(which(!is.na(x)))
           , juljo = dplyr::last(which(!is.na(x)))
           , GKiTail = tail(which(!is.na(x)), 1)
           , GKiCum = which.max(cumsum(!is.na(x)))
           , GKiRev = length(x) - which.min(rev(is.na(x))) + 1
           , GKiMatch = length(x) - match(FALSE, is.na(rev(x))) + 1
           , GKiFor = idxLNNA(x)
             )

x <- numeric(1e6)
microbenchmark(list = fun, control=list(order="block"))
#Unit: microseconds
#     expr      min        lq       mean    median       uq        max neval cld
#    Dason 4855.744 5740.1355 7941.21809 7082.5535 7671.371 107165.201   100  bc
#    juljo 4145.322 4616.7815 5756.38147 6134.9200 6625.008   7378.724   100  b 
#  GKiTail 4082.716 4434.3880 5576.70509 6051.1465 6489.966   7433.579   100  b 
#   GKiCum 6552.213 7445.1525 8632.12253 8988.8700 9420.481  16791.845   100   c
#   GKiRev 4005.929 4138.4735 5845.70457 4212.7470 5851.034 101665.685   100  b 
# GKiMatch 5180.600 5483.8545 7507.82723 5998.2760 7373.458 108327.967   100  bc
#   GKiFor    1.541    1.5775    2.16462    1.6145    1.724     20.436   100 a  

x <- rep(NA, 1e6) #Dason, GKiCum and GKiRev Fail
microbenchmark(list = fun[-c(1,4,5)], control=list(order="block"))
#Unit: milliseconds
#     expr        min         lq       mean     median         uq        max neval cld
#    juljo   3.011272   3.076340   3.525396   3.111676   3.494768   6.367839   100 a  
#  GKiTail   2.942336   3.014327   3.529691   3.063891   3.809653   6.136984   100 a  
# GKiMatch   4.928626   4.975369   7.490588   5.039941   6.823780  98.194653   100  b 
#   GKiFor 155.078444 159.314918 163.706542 160.168266 163.464146 258.136977   100   c

x <- numeric(0) #Dason Fails
microbenchmark(list = fun[-1], control=list(order="block"))
Unit: nanoseconds
#     expr   min      lq     mean  median      uq    max neval  cld
#    juljo 26794 27324.0 28694.75 27640.0 27933.0 120143   100    d
#  GKiTail  6746  7027.5  7396.45  7206.5  7432.5  21898   100   c 
#   GKiCum   869   880.0   947.72   890.0   948.0   3403   100 a   
#   GKiRev  2466  2527.0  2657.99  2565.5  2652.0   8071   100  b  
# GKiMatch  2739  2807.5  2919.78  2862.5  2935.5   5651   100  b  
#   GKiFor   492   512.5   671.74   537.5   604.5   9088   100 a