Assim como a pergunta diz. Existe uma maneira mais rápida de fazer o que é feito abaixo quando o tamanho do vetor é muito grande (> 10M entradas) usando a base R?
O código abaixo funciona, mas quando o tamanho do vetor cresce, ele se torna lento por razões que deveriam ser óbvias. Neste exemplo em particular, um loop for pode ser mais rápido, mas se o primeiro valor NA estiver muito longe do início do vetor, talvez não...
set.seed(1)
x <- c(rep(NA, 3), sample(c(T,F), size=5e7, replace=T))
min(which(!is.na(x))) #4
Um
Rcpp
loop for deve ser rápido mesmo se o primeiro non-NA
value não estiver particularmente próximo do início. A ideia básica é que você não precisa continuar iterando depois de ter encontrado o primeiro valor.Referências
Aqui estão alguns benchmarks para alguns vetores de comprimento
1e3
para1e8
. Para um vetor de comprimento 1.000, isso é cerca de 9 vezes mais rápido do que a abordagem R. Para um vetor de comprimento 100.000.000, é em média mais de um milhão de vezes mais rápido. Adicionei as outras respostas ao benchmark também.which.min()
é mais rápido do quemin(which())
, mas para o maior vetor aqui, isso ainda é cerca de 200.000 vezes mais rápido do que isso.Saída:
Você pode usar
which.min
andwhich.max
(semis.na()
), pois como diz o manual:e você verá
Observação
Do ponto de vista de benchmarking, parece
is.na
ser um operador caro do ponto de vista da velocidade, especialmente quando o tamanho do array aumentaCheguei muito atrasado na festa, mas não vi ninguém mencionar Position(), que faz o que você está procurando e interrompe a varredura assim que uma correspondência é encontrada:
Um pouco mais rápido do que usar
min
e basear Rencontra o primeiro valor não-NA entre 100.000.000 de valores em menos de um segundo, mesmo em uma CPU ruim.
em um Intel Mac, OS 13.5.2
Editar: reteste com entrada puramente lógica
Não sei como o C++ se sairia se fosse executado em entradas numéricas, mas não declarasse "lógico".