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
tailfunción:Lo bueno
tailes 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 elxsubconjunto), 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), dondemylastse 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
revoendya que claramente no lo esO(1)(y las expresiones resultantes se evalúan de manera no perezosa).tailydplyr::lastno 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 quemylasten 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
xal 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
lastdelpastecspaquete,headytail(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
headpara 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 estotailes 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 aplicarreva 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.tableincluye lalastfunció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
NROWhaga 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.nrownrow,NROWtrata un vector como una matriz de 1 columna.El paquete xts proporciona una
lastfunción:fuente