簡體   English   中英

如何反轉R中數據幀的順序

[英]How to reverse the order of a dataframe in R

我無休止地尋找這個,不知何故沒有解決這個簡單的問題。

我有一個名為 Prices 的數據框,其中有 4 列,其中一列是歷史日期列表 - 其他 3 列是產品價格列表。

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

該列表有 252 個價格。 如何將我的輸出與列表底部的最新日期一起存儲,並將相應價格與列表底部的最新價格一起列出?

另一個tidyverse解決方案,我認為最簡單的解決方案是:

df %>% map_df(rev)

或者只使用purrr::map_df我們可以做map_df(df, rev)

如果您只想反轉數據框中行的順序,您可以執行以下操作:

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

只是為了完整性。 這里其實沒有必要調用seq 您可以只使用: -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

我在這里的試驗中最快的方法是使用df<-df[dim(df)[1]:1,] 然而,使用nrow而不是dim只是稍微慢了一點。 使這是個人喜好的問題。

在這里使用seq肯定會減慢進程的速度。

2018 年 9 月更新:

從速度的角度來看,這里幾乎沒有理由使用dplyr 對於大約 90% 的用戶來說,基本的 R 功能應該足夠了。 另外 10% 需要使用dplyr來查詢數據庫或需要將代碼翻譯成另一種語言。

## 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

另一個tidyverse解決方案是:

df %>% arrange(desc(row_number()))

這是關於OP如何反轉行順序的問題的dplyrtidyverse )解決方案。

假設數據幀被稱為df ,那么我們可以這樣做:

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

說明:“。” 占位符將輸入管道數據框作為輸入。 然后rownames(df)成為索引的向量, 1:nrow(df) rev顛倒順序和arrange重新排序df相應。

沒有管道,以下內容也是如此:

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

如果OP首先將其日期轉換為DatePOSIX格式,如評論中所述,那么他當然可以簡單地使用df %>% arrange(Date)

但第一種方法是回答OP的問題。

另一種選擇是按要排序的向量對列表進行排序,

> 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

那么如果你如此傾向,你想顛倒順序,顛倒它,

> 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

如果您想在基本 R 中執行此操作,請使用:

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

此處發布的所有其他基本 R 解決方案在零行數據幀( seq(0,1) == c(0, 1) ,這就是我們使用seq_len )或單列數據幀( data.frame(a=7:9)[3:1,] == 9:7 )的邊緣情況下都會出現問題data.frame(a=7:9)[3:1,] == 9:7 ,這就是我們使用, drop = FALSE的原因。

如果你想堅持使用基礎 R,你也可以使用lapply()

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM