344 votes

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

Supposons que j'ai un vecteur qui est imbriqué dans un cadre de données à un ou deux niveaux. Existe-t-il un moyen rapide d'accéder à la dernière valeur, sans utiliser la fonction length() fonction ? Quelque chose comme la fonction PERL $# var spécial ?

Je voudrais donc quelque chose comme :

dat$vec1$vec2[$#]

au lieu de

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

1 votes

Je ne suis en aucun cas un expert de R, mais une rapide recherche sur google a donné ceci : < stat.ucl.ac.be/ISdidactique/Rhelp/library/pastecs/html/ > Il semble y avoir une fonction "dernier".

0 votes

2 votes

MATLAB dispose de la notation "myvariable(end-k)" où k est un entier inférieur à la longueur du vecteur qui retournera le (longueur(myvariable)-k)ème élément. Ce serait bien de l'avoir dans R.

461voto

lindelof Points 9802

J'utilise le tail fonction :

tail(vector, n=1)

Ce qui est bien avec tail c'est qu'il fonctionne aussi sur les dataframes, contrairement à l'option x[length(x)] idiome.

6 votes

Cependant x[length(x[,1]),] fonctionne sur les données ou x[dim(x)[1],]

31 votes

Notez que pour les cadres de données, length(x) == ncol(x) donc c'est définitivement faux, et dim(x)[1] peut être plus descriptivement écrit nrow(x).

2 votes

@hadley - la suggestion de kpierce8 de x[length(x[,1]),] n'est pas erronée (notez la virgule dans l'expression x ), mais c'est certainement gênant.

136voto

Gregg Lind Points 6905

Si vous cherchez quelque chose d'aussi agréable que la notation x[-1] de Python, je pense que vous n'avez pas de chance. L'idiome standard est

x[length(x)]  

mais il est assez facile d'écrire une fonction pour le faire :

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

Cette fonctionnalité manquante dans R m'ennuie aussi !

3 votes

Bonne idée de proposer un exemple de fonction +1

1 votes

Notez que si vous voulez les derniers éléments d'un vecteur plutôt que le dernier élément, il n'est pas nécessaire de faire quelque chose de complexe pour adapter cette solution. La vectorisation de R vous permet de faire des choses simples comme obtenir les quatre derniers éléments de x en faisant x[length(x)-0:3] .

54voto

Florian Jenn Points 1556

Combinaison de de lindelof et Gregg Lind des idées :

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

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

Contrairement à last de la pastecs paquet, head et tail (de utils ) fonctionnent non seulement sur des vecteurs mais aussi sur des cadres de données, etc. et peuvent également renvoyer des données " sans les n premiers/ derniers éléments ", par exemple

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

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

8 votes

Veuillez noter que mon benchmark ci-dessous montre que cela est plus lent que x[length(x)] par un facteur de 30 en moyenne pour les plus grands vecteurs !

19voto

scuerda Points 59

Je viens de tester ces deux approches sur un cadre de données de 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 

Ainsi, en supposant que vous travaillez avec des vecteurs, l'accès à la position de la longueur est nettement plus rapide.

3 votes

Pourquoi ne pas tester tail(strsplit(x,".",fixed=T)[[1]],1) pour le 2ème cas ? Pour moi, le principal avantage de la tail est que vous pouvez l'écrire en une seule ligne ;)

12voto

James Points 24725

Une autre méthode consiste à prendre le premier élément du vecteur inversé :

rev(dat$vect1$vec2)[1]

8 votes

Ce sera coûteux cependant !

1 votes

Veuillez noter qu'il s'agit d'une opération dont le coût de calcul est linéaire par rapport à la longueur de l'entrée ; en d'autres termes, bien que O(n), elle n'est pas O(1). Voir aussi mon benchmark ci-dessous pour les chiffres réels.

0 votes

@anonymous A moins que vous n'utilisiez un itérateur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X