tamaño studio matrices funcion eliminar datos data contar r indexing

studio - Obtener los últimos n elementos de un vector. ¿Hay una forma mejor que usar la función length()?



seq en r (6)

Si, por el bien de un argumento, quiero los últimos cinco elementos de un vector de 10 longitudes en Python, puedo usar el operador "-" en el índice de rango así:

>>> x = range(10) >>> x [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> x[-5:] [5, 6, 7, 8, 9] >>>

¿Cuál es la mejor manera de hacer esto en R? ¿Hay una manera más limpia que mi técnica actual que es usar la función de longitud ()?

> x <- 0:9 > x [1] 0 1 2 3 4 5 6 7 8 9 > x[(length(x) - 4):length(x)] [1] 5 6 7 8 9 >

La pregunta está relacionada con el análisis de series de tiempo por cierto donde a menudo es útil trabajar solo en datos recientes.


¿Qué hay de rev(x)[1:5] ?

x<-1:10 system.time(replicate(10e6,tail(x,5))) user system elapsed 138.85 0.26 139.28 system.time(replicate(10e6,rev(x)[1:5])) user system elapsed 61.97 0.25 62.23


Aquí hay una función para hacerlo y parece bastante rápido.

endv<-function(vec,val) { if(val>length(vec)) { stop("Length of value greater than length of vector") }else { vec[((length(vec)-val)+1):length(vec)] } }

USO:

test<-c(0,1,1,0,0,1,1,NA,1,1) endv(test,5) endv(LETTERS,5)

PUNTO DE REFERENCIA:

test replications elapsed relative 1 expression(tail(x, 5)) 100000 5.24 6.469 2 expression(x[seq.int(to = length(x), length.out = 5)]) 100000 0.98 1.210 3 expression(x[length(x) - (4:0)]) 100000 0.81 1.000 4 expression(endv(x, 5)) 100000 1.37 1.691


La desaprobación de la tail aquí basada solo en la velocidad realmente no parece enfatizar que parte de la velocidad más lenta proviene del hecho de que la cola es más segura para trabajar, si no estás seguro de que la longitud de x excederá n , la cantidad de elementos que desea subconjuntar:

x <- 1:10 tail(x, 20) # [1] 1 2 3 4 5 6 7 8 9 10 x[length(x) - (0:19)] #Error in x[length(x) - (0:19)] : # only 0''s may be mixed with negative subscripts

Tail simplemente devolverá el número máximo de elementos en lugar de generar un error, por lo que no es necesario que haga ningún error para verificarlo usted mismo. Una gran razón para usarlo. Código de limpieza más seguro, si microsegundos / milisegundos adicionales no le importan mucho en su uso.


Puedes hacer exactamente lo mismo en R con dos personajes más:

x <- 0:9 x[-5:-1] [1] 5 6 7 8 9

o

x[-(1:5)]


Solo agrego aquí algo relacionado. Se quería acceder a un vector con índices de back-end, es decir, escribiendo algo como tail(x, i) pero para devolver x[length(x) - i + 1] y no toda la cola.

Siguiendo los comentarios, comparaté dos soluciones:

accessRevTail <- function(x, n) { tail(x,n)[1] } accessRevLen <- function(x, n) { x[length(x) - n + 1] } microbenchmark::microbenchmark(accessRevLen(1:100, 87), accessRevTail(1:100, 87)) Unit: microseconds expr min lq mean median uq max neval accessRevLen(1:100, 87) 1.860 2.3775 2.84976 2.803 3.2740 6.755 100 accessRevTail(1:100, 87) 22.214 23.5295 28.54027 25.112 28.4705 110.833 100

Entonces, parece que en este caso, incluso para vectores pequeños, la tail es muy lenta en comparación con el acceso directo


ver ?tail y ?head para algunas funciones convenientes:

> x <- 1:10 > tail(x,5) [1] 6 7 8 9 10

Por el bien del argumento: todo menos los últimos cinco elementos serían:

> head(x,n=-5) [1] 1 2 3 4 5

Como dice @Martin Morgan en los comentarios, hay otras dos posibilidades que son más rápidas que la solución de cola, en caso de que tenga que llevar a cabo esto un millón de veces en un vector de 100 millones de valores. Para ser legible, iría con la cola.

test elapsed relative tail(x, 5) 38.70 5.724852 x[length(x) - (4:0)] 6.76 1.000000 x[seq.int(to = length(x), length.out = 5)] 7.53 1.113905

Código de evaluación comparativa:

require(rbenchmark) x <- 1:1e8 do.call( benchmark, c(list( expression(tail(x,5)), expression(x[seq.int(to=length(x), length.out=5)]), expression(x[length(x)-(4:0)]) ), replications=1e6) )