vectores valor vacio sustituir seleccionar por ordenar listas data crear columnas buscar r vector

valor - sustituir na por 0 en r



¿Cómo acceder al último valor en un vector? (11)

Acabo de comparar estos dos enfoques en el marco de datos con 663,552 filas usando el siguiente código:

system.time( resultsByLevel$subject <- sapply(resultsByLevel$variable, function(x) { s <- strsplit(x, ".", fixed=TRUE)[[1]] s[length(s)] }) ) user system elapsed 3.722 0.000 3.594

y

system.time( resultsByLevel$subject <- sapply(resultsByLevel$variable, function(x) { s <- strsplit(x, ".", fixed=TRUE)[[1]] tail(s, n=1) }) ) user system elapsed 28.174 0.000 27.662

Entonces, asumiendo que estás trabajando con vectores, acceder a la posición de longitud es significativamente más rápido.

Supongamos que tengo un vector que está anidado en un marco de datos de uno o dos niveles. ¿Hay una forma rápida y sucia de acceder al último valor sin utilizar la función length() ? Algo ala $# especial var de PERL?

Así que me gustaría algo como:

dat$vec1$vec2[$#]

en lugar de

dat$vec1$vec2[length(dat$vec1$vec2)]


Combinando las ideas de lindelof y gregg lind:

last <- function(x) { tail(x, n = 1) }

Trabajando en el indicador, normalmente omito el " n= ", es decir, la tail(x, 1) .

A diferencia del last del paquete de pastecs , la head y la tail (de utils ) funcionan no solo en vectores sino también en marcos de datos, etc., y también pueden devolver datos "sin los primeros / últimos n elementos", por ejemplo

but.last <- function(x) { head(x, n = -1) }

(Tenga en cuenta que debe usar la head para esto, en lugar de la tail ).


De que se trata

> a <- c(1:100,555) > a[NROW(a)] [1] 555


El paquete dplyr incluye una función last() :

last(mtcars$mpg) # [1] 21.4


El paquete data.table incluye la last función.

library(data.table) last(c(1:10)) # [1] 10


El paquete xts proporciona una last función:

library(xts) a <- 1:100 last(a) [1] 100


Otra forma es tomar el primer elemento del vector invertido:

rev(dat$vect1$vec2)[1]


Para responder a esto no desde un punto de vista estético sino orientado hacia el rendimiento, he puesto todas las sugerencias anteriores a través de un punto de referencia . Para ser precisos, he considerado las sugerencias.

  • x[length(x)]
  • mylast(x) , donde mylast es una función de C ++ implementada a través de Rcpp,
  • tail(x, n=1)
  • dplyr::last(x)
  • x[end(x)[1]]]
  • rev(x)[1]

y los aplicó a vectores aleatorios de varios tamaños (10 ^ 3, 10 ^ 4, 10 ^ 5, 10 ^ 6 y 10 ^ 7). Antes de ver los números, creo que debería quedar claro que cualquier cosa que se vuelva notablemente más lenta con un mayor tamaño de entrada (es decir, cualquier cosa que no sea O (1)) no es una opción. Aquí está el código que utilicé:

Rcpp::cppFunction(''double mylast(NumericVector x) { int n = x.size(); return x[n-1]; }'') options(width=100) for (n in c(1e3,1e4,1e5,1e6,1e7)) { x <- runif(n); print(microbenchmark::microbenchmark(x[length(x)], mylast(x), tail(x, n=1), dplyr::last(x), x[end(x)[1]], rev(x)[1]))}

Me da

Unit: nanoseconds expr min lq mean median uq max neval x[length(x)] 171 291.5 388.91 337.5 390.0 3233 100 mylast(x) 1291 1832.0 2329.11 2063.0 2276.0 19053 100 tail(x, n = 1) 7718 9589.5 11236.27 10683.0 12149.0 32711 100 dplyr::last(x) 16341 19049.5 22080.23 21673.0 23485.5 70047 100 x[end(x)[1]] 7688 10434.0 13288.05 11889.5 13166.5 78536 100 rev(x)[1] 7829 8951.5 10995.59 9883.0 10890.0 45763 100 Unit: nanoseconds expr min lq mean median uq max neval x[length(x)] 204 323.0 475.76 386.5 459.5 6029 100 mylast(x) 1469 2102.5 2708.50 2462.0 2995.0 9723 100 tail(x, n = 1) 7671 9504.5 12470.82 10986.5 12748.0 62320 100 dplyr::last(x) 15703 19933.5 26352.66 22469.5 25356.5 126314 100 x[end(x)[1]] 13766 18800.5 27137.17 21677.5 26207.5 95982 100 rev(x)[1] 52785 58624.0 78640.93 60213.0 72778.0 851113 100 Unit: nanoseconds expr min lq mean median uq max neval x[length(x)] 214 346.0 583.40 529.5 720.0 1512 100 mylast(x) 1393 2126.0 4872.60 4905.5 7338.0 9806 100 tail(x, n = 1) 8343 10384.0 19558.05 18121.0 25417.0 69608 100 dplyr::last(x) 16065 22960.0 36671.13 37212.0 48071.5 75946 100 x[end(x)[1]] 360176 404965.5 432528.84 424798.0 450996.0 710501 100 rev(x)[1] 1060547 1140149.0 1189297.38 1180997.5 1225849.0 1383479 100 Unit: nanoseconds expr min lq mean median uq max neval x[length(x)] 327 584.0 1150.75 996.5 1652.5 3974 100 mylast(x) 2060 3128.5 7541.51 8899.0 9958.0 16175 100 tail(x, n = 1) 10484 16936.0 30250.11 34030.0 39355.0 52689 100 dplyr::last(x) 19133 47444.5 55280.09 61205.5 66312.5 105851 100 x[end(x)[1]] 1110956 2298408.0 3670360.45 2334753.0 4475915.0 19235341 100 rev(x)[1] 6536063 7969103.0 11004418.46 9973664.5 12340089.5 28447454 100 Unit: nanoseconds expr min lq mean median uq max neval x[length(x)] 327 722.0 1644.16 1133.5 2055.5 13724 100 mylast(x) 1962 3727.5 9578.21 9951.5 12887.5 41773 100 tail(x, n = 1) 9829 21038.0 36623.67 43710.0 48883.0 66289 100 dplyr::last(x) 21832 35269.0 60523.40 63726.0 75539.5 200064 100 x[end(x)[1]] 21008128 23004594.5 37356132.43 30006737.0 47839917.0 105430564 100 rev(x)[1] 74317382 92985054.0 108618154.55 102328667.5 112443834.0 187925942 100

Esto descarta inmediatamente cualquier cosa que involucre rev o end ya que claramente no son O(1) (y las expresiones resultantes se evalúan de manera no perezosa). tail y dplyr::last no están lejos de ser O(1) pero también son considerablemente más lentos que mylast(x) y x[length(x)] . Como mylast(x) es más lento que x[length(x)] y no proporciona beneficios (más bien, es personalizado y no maneja con gracia un vector vacío), creo que la respuesta es clara: use x[length(x)] .


Si estás buscando algo tan bonito como la notación x [-1] de Python, creo que no tienes suerte. El idioma estándar es

x[length(x)]

pero es bastante fácil escribir una función para hacer esto:

last <- function(x) { return( x[length(x)] ) }

Esta característica que falta en R me molesta también!


Tengo otro método para encontrar el último elemento en un vector. Digamos que el vector es a .

> a<-c(1:100,555) > end(a) #Gives indices of last and first positions [1] 101 1 > a[end(a)[1]] #Gives last element in a vector [1] 555

¡Ahí tienes!


Yo uso la función tail() :

tail(vector, n=1)

Lo bueno de tail() es que también funciona en marcos de datos, a diferencia del idioma x[length(x)] .