web-dev-qa-db-fra.com

Comment inverser l'ordre d'une trame de données dans R

J'ai sans cesse cherché cela et en quelque sorte rien n'a résolu ce problème simple.

J'ai une trame de données appelée Prix dans laquelle il y a 4 colonnes, dont l'une est une liste de dates historiques - les 3 autres sont des listes de prix pour les produits.

1   10/10/2016  53.14   50.366  51.87
2   07/10/2016  51.93   49.207  50.38
3   06/10/2016  52.51   49.655  50.98
4   05/10/2016  51.86   49.076  50.38
5   04/10/2016  50.87   48.186  49.3
6   03/10/2016  50.89   48.075  49.4
7   30/09/2016  50.19   47.384  48.82
8   29/09/2016  49.81   46.924  48.4
9   28/09/2016  49.24   46.062  47.65
10  27/09/2016  46.52   43.599  45.24

La liste est longue de 252 prix. Comment puis-je conserver ma sortie avec la dernière date en bas de la liste et les prix correspondants listés avec les derniers prix en bas de la liste?

22
jmn8

Si vous souhaitez simplement inverser l'ordre des lignes dans une trame de données, vous pouvez effectuer les opérations suivantes:

df<- df[seq(dim(df)[1],1),]
12
user7559006

Par souci d'exhaustivité. Il n'est en fait pas nécessaire d'appeler seq ici. Vous pouvez simplement utiliser le : - R-logic:

### Create some sample data
n=252
sampledata<-data.frame(a=sample(letters,n,replace=TRUE),b=rnorm(n,1,0.7),
                       c=rnorm(n,1,0.6),d=runif(n))

### Compare some different ways to reorder the dataframe
myfun1<-function(df=sampledata){df<-df[seq(nrow(df),1),]}
myfun2<-function(df=sampledata){df<-df[seq(dim(df)[1],1),]}
myfun3<-function(df=sampledata){df<-df[dim(df)[1]:1,]}
myfun4<-function(df=sampledata){df<-df[nrow(df):1,]}

### Microbenchmark the functions


microbenchmark::microbenchmark(myfun1(),myfun2(),myfun3(),myfun4(),times=1000L)
    Unit: microseconds
         expr    min     lq      mean  median      uq      max neval
     myfun1() 63.994 67.686 117.61797 71.3780 87.3765 5818.494  1000
     myfun2() 63.173 67.686  99.29120 70.9680 87.7865 2299.258  1000
     myfun3() 56.610 60.302  92.18913 62.7635 76.9155 3241.522  1000
     myfun4() 56.610 60.302  99.52666 63.1740 77.5310 4440.582  1000

Le moyen le plus rapide dans mon essai ici consistait à utiliser df<-df[dim(df)[1]:1,]. Cependant, l'utilisation de nrow au lieu de dim n'est que légèrement plus lente. En faire une question de préférence personnelle.

L'utilisation de seq ici ralentit définitivement le processus.

MISE À JOUR septembre 2018:

Du point de vue de la vitesse, il n'y a pas de raison d'utiliser dplyr ici. Pour peut-être 90% des utilisateurs, la fonctionnalité R de base devrait suffire. Les 10% restants doivent utiliser dplyr pour interroger une base de données ou ont besoin d'une traduction de code dans une autre langue.

## hmhensen's function
dplyr_fun<-function(df=sampledata){df %>% arrange(rev(rownames(.)))}

microbenchmark::microbenchmark(myfun3(),myfun4(),dplyr_fun(),times=1000L)
Unit: microseconds
        expr    min      lq      mean  median      uq    max neval
    myfun3()   55.8   69.75  132.8178  103.85  139.95 8949.3  1000
    myfun4()   55.9   68.40  115.6418  100.05  135.00 2409.1  1000
 dplyr_fun() 1364.8 1541.15 2173.0717 1786.10 2757.80 8434.8  1000
10
5th

Une autre solution tidyverse et je pense que la plus simple est:

df %>% map_df(rev)

ou en utilisant simplement purrr::map_df, nous pouvons faire map_df(df, rev).

6
pasipasi

Voici une solution dplyr (tidyverse) à la question de l'OP de savoir comment inverser l'ordre des lignes.

En supposant que la trame de données est appelée df, alors nous pouvons faire:

df %>% arrange(rev(rownames(.)))

Explication: l'espace réservé "." Prend en entrée le bloc de données canalisé. Puis rownames(df) devient le vecteur d'indices, 1:nrow(df). rev inverse la ordre et arrange réordonne df en conséquence.

Sans le tuyau, ce qui suit fait la même chose:

arrange(df, rev(rownames(df)))

Si l'OP aurait d'abord converti ses dates au format Date ou POSIX comme décrit dans les commentaires, alors il pourrait, bien sûr, simplement utiliser df %>% arrange(Date).

Mais la première méthode est celle qui répond à la question du PO.

3
hmhensen

Si vous souhaitez vous en tenir à la base R, vous pouvez également utiliser lapply().

do.call(cbind, lapply(df, rev))
0
Joe