Supongamos que tengo un vector que está anidado en un marco de datos de uno o dos niveles. ¿Hay alguna forma rápida y sucia de acceder al último valor, sin usar la length()
función? ¿Algo especial de ala PERL $#
?
Entonces me gustaría algo como:
dat$vec1$vec2[$#]
en vez de
dat$vec1$vec2[length(dat$vec1$vec2)]
Respuestas:
Yo uso la
tail
función:Lo bueno
tail
es que también funciona en marcos de datos, a diferencia delx[length(x)]
idioma.fuente
x[length(x[,1]),]
no es incorrecta (tenga en cuenta la coma en elx
subconjunto), pero ciertamente es incómoda.x[length(x)]
en un factor de 30 en promedio para vectores más grandes!tail(vector, n=1)-tail(vector, n=2)
Para responder esto no desde un punto de vista estético sino orientado al 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)
, dondemylast
se implementa una función C ++ 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 mirar 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 usé:
Me da
Esto descarta inmediatamente cualquier cosa que implique
rev
oend
ya que claramente no lo esO(1)
(y las expresiones resultantes se evalúan de manera no perezosa).tail
ydplyr::last
no están lejos de ser,O(1)
pero también son considerablemente más lentos quemylast(x)
yx[length(x)]
. Comomylast(x)
es más lentox[length(x)]
y no proporciona beneficios (más bien, es personalizado y no maneja un vector vacío con gracia), creo que la respuesta es clara: por favor, usex[length(x)]
.fuente
mylastR=function(x) {x[length(x)}
Es más rápido quemylast
en Rcpp, pero una vez más lento que escribirx[length(x)]
directamenteSi está buscando algo tan bueno como la notación x [-1] de Python, creo que no tiene suerte. El idioma estándar es
pero es bastante fácil escribir una función para hacer esto:
¡Esta característica que falta en R también me molesta!
fuente
x
al hacerx[length(x)-0:3]
.Combinando las ideas de lindelof y Gregg Lind :
Al trabajar en el indicador, generalmente omito el
n=
, es decirtail(x, 1)
.A diferencia
last
delpastecs
paquete,head
ytail
(desdeutils
) funcionan no solo en vectores sino también en marcos de datos, etc., y también pueden devolver datos " sin el primer / último n elementos ", por ejemplo(Tenga en cuenta que tiene que usar
head
para esto, en lugar detail
).fuente
x[length(x)]
en un factor de 30 en promedio para vectores más grandes!El paquete dplyr incluye una función
last()
:fuente
x[[length(x)]]
otra vez.last()
y almacenar esa función en algún lugar, como lo han hecho varias personas anteriormente. Obtiene la legibilidad mejorada de una función, y la portabilidad proviene de CRAN para que otra persona pueda ejecutar el código.mtcars$mpg %>% last
, según su preferencia.x[[length(x)]]
, sin embargo!Acabo de comparar estos dos enfoques en el marco de datos con 663,552 filas usando el siguiente código:
y
Entonces, suponiendo que esté trabajando con vectores, acceder a la posición de longitud es significativamente más rápido.
fuente
tail(strsplit(x,".",fixed=T)[[1]],1)
para el segundo caso? Para mí, la principal ventaja de estotail
es que puedes escribirlo en una línea. ;)Otra forma es tomar el primer elemento del vector invertido:
fuente
[1]
para acceder al primer elemento y (2) mientras puedes aplicarrev
a un iterador, no se comporta como se esperaba: solo trata el objeto iterador como una lista de sus miembros y revierte eso.El paquete
data.table
incluye lalast
funciónfuente
x[[length(x)]]
otra vez.Tengo otro método para encontrar el último elemento en un vector. Digamos que el vector es
a
.Ahí tienes!
fuente
De que se trata
fuente
NROW
haga lo que esperaría en muchos tipos de datos diferentes, pero es esencialmente lo mismoa[length(a)]
que OP espera evitar. Usar el ejemplo de OP de un vector anidadodat$vec1$vec2[NROW(dat$vec1$vec2)]
sigue siendo bastante complicado.nrow
nrow
,NROW
trata un vector como una matriz de 1 columna.El paquete xts proporciona una
last
función:fuente