How to reverse the order of a dataframe in R

前端 未结 7 791
终归单人心
终归单人心 2021-01-03 18:37

I\'ve endlessly looked for this and somehow nothing has solved this simple problem.

I have a dataframe called Prices in which there are 4 columns, one of wh

相关标签:
7条回答
  • 2021-01-03 18:40

    Yet another tidyverse solution is:

    df %>% arrange(desc(row_number()))
    
    0 讨论(0)
  • 2021-01-03 18:43

    Just for completeness sake. There is actually no need to call seq here. You can just use the :-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
    

    The fastest way in my trial here was to use df<-df[dim(df)[1]:1,]. However using nrow instead of dim is only slightly slower. Making this a question of personal preference.

    Using seq here definitely slows the process down.

    UPDATE September 2018:

    From a speed view there is little reason to use dplyr here. For maybe 90% of users the basic R functionality should suffice. The other 10% need to use dplyr for querying a database or need code translation into another language.

    ## 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
    
    0 讨论(0)
  • 2021-01-03 18:44

    Another option is to order the list by the vector you want to sort it by,

    > data[order(data$Date), ]
    # A tibble: 10 x 4
       Date                priceA priceB priceC
       <dttm>               <dbl>  <dbl>  <dbl>
     1 2016-09-27 00:00:00   46.5   43.6   45.2
     2 2016-09-28 00:00:00   49.2   46.1   47.6
     3 2016-09-29 00:00:00   49.8   46.9   48.4
     4 2016-09-30 00:00:00   50.2   47.4   48.8
     5 2016-10-03 00:00:00   50.9   48.1   49.4
     6 2016-10-04 00:00:00   50.9   48.2   49.3
     7 2016-10-05 00:00:00   51.9   49.1   50.4
     8 2016-10-06 00:00:00   52.5   49.7   51.0
     9 2016-10-07 00:00:00   51.9   49.2   50.4
    10 2016-10-10 00:00:00   53.1   50.4   51.9
    

    Then if you are so inclined, you want to flip the order, reverse it,

    > data[rev(order(data$Date)), ]
    # A tibble: 10 x 4
       Date                priceA priceB priceC
       <dttm>               <dbl>  <dbl>  <dbl>
     1 2016-10-10 00:00:00   53.1   50.4   51.9
     2 2016-10-07 00:00:00   51.9   49.2   50.4
     3 2016-10-06 00:00:00   52.5   49.7   51.0
     4 2016-10-05 00:00:00   51.9   49.1   50.4
     5 2016-10-04 00:00:00   50.9   48.2   49.3
     6 2016-10-03 00:00:00   50.9   48.1   49.4
     7 2016-09-30 00:00:00   50.2   47.4   48.8
     8 2016-09-29 00:00:00   49.8   46.9   48.4
     9 2016-09-28 00:00:00   49.2   46.1   47.6
    10 2016-09-27 00:00:00   46.5   43.6   45.2
    
    0 讨论(0)
  • 2021-01-03 18:47

    If you want to stick with base R, you could also use lapply().

    do.call(cbind, lapply(df, rev))
    
    0 讨论(0)
  • 2021-01-03 18:52

    Another tidyverse solution and I think the simplest one is:

    df %>% map_df(rev)

    or using just purrr::map_df we can do map_df(df, rev).

    0 讨论(0)
  • 2021-01-03 18:54

    If you wanted to do this in base R use:

    df <- df[rev(seq_len(nrow(df))), , drop = FALSE]
    

    All other base R solutions posted here will have problems in the edge cases of zero row data frames (seq(0,1) == c(0, 1), that's why we use seq_len) or single column data frames (data.frame(a=7:9)[3:1,] == 9:7, that's why we use , drop = FALSE).

    0 讨论(0)
提交回复
热议问题