Comment accéder à la dernière valeur dans un vecteur?

Supposons que je dispose d’un vecteur nested dans un cadre de données à un ou deux niveaux. Existe-t-il un moyen rapide et sale d’accéder à la dernière valeur, sans utiliser la fonction length() ? Quelque chose comme le $# spécial var de PERL?

Donc je voudrais quelque chose comme:

 dat$vec1$vec2[$#] 

au lieu de

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

J’utilise la fonction tail() :

 tail(vector, n=1) 

Ce qui est bien avec tail() c’est qu’elle fonctionne aussi sur les dataframes, contrairement au langage x[length(x)] .

Si vous cherchez quelque chose d’aussi beau que la notation x [-1] de Python, je pense que vous n’avez pas de chance. Le langage standard est

 x[length(x)] 

mais c’est assez facile d’écrire une fonction pour faire ceci:

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

Cette fonctionnalité manquante dans R m'agace aussi!

Pour répondre à cela non pas d’un sharepoint vue esthétique mais axé sur la performance, j’ai présenté toutes les suggestions ci-dessus à travers une référence . Pour être précis, j’ai considéré les suggestions

  • x[length(x)]
  • mylast(x) , où mylast est une fonction C ++ implémentée via Rcpp,
  • tail(x, n=1)
  • dplyr::last(x)
  • x[end(x)[1]]]
  • rev(x)[1]

et les a appliqués à des vecteurs aléatoires de différentes tailles (10 ^ 3, 10 ^ 4, 10 ^ 5, 10 ^ 6 et 10 ^ 7). Avant d’examiner les chiffres, je pense qu’il devrait être clair que tout ce qui devient sensiblement plus lent avec une plus grande taille d’entrée (c.-à-d. Tout ce qui n’est pas O (1)) n’est pas une option. Voici le code que j’ai utilisé:

 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]))} 

Ça me donne

 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 

Cela élimine immédiatement tout ce qui implique un tour ou une end car ils ne sont clairement pas O(1) (et les expressions résultantes sont évaluées de manière non paresseuse). tail et dplyr::last ne sont pas loin d'être O(1) mais ils sont aussi beaucoup plus lents que mylast(x) et x[length(x)] . Puisque mylast(x) est plus lent que x[length(x)] et ne procure aucun avantage (plutôt, il est personnalisé et ne gère pas correctement un vecteur vide), je pense que la réponse est claire: veuillez utiliser x[length(x)] .

En combinant les idées de Lindelof et Gregg Lind:

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

En travaillant à l'invite, j'omets généralement le " n= ", c'est-à-dire la tail(x, 1) .

Contrairement au paquetage last from pastecs , head et tail (from utils ) fonctionnent non seulement sur les vecteurs, mais aussi sur les trames de données, etc.

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

(Notez que vous devez utiliser la head pour cela, au lieu de la tail .)

Je viens de comparer ces deux approches sur un bloc de données avec 663 552 lignes en utilisant le code suivant:

 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 

et

 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 

Donc, en supposant que vous travaillez avec des vecteurs, il est beaucoup plus rapide d'accéder à la position de longueur.

Une autre façon consiste à prendre le premier élément du vecteur inversé:

 rev(dat$vect1$vec2)[1] 

Le package dplyr comprend une fonction last() :

 last(mtcars$mpg) # [1] 21.4 

J’ai une autre méthode pour trouver le dernier élément dans un vecteur. Disons que le vecteur est 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 

Voilà!

Le package data.table inclut la last fonction

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

De quoi s’agit-il

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

Le package xts fournit une last fonction:

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