繁体   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