我无休止地寻找这个,不知何故没有解决这个简单的问题。
我有一个名为Price的数据框,其中有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个价格。如何将我的输出存储在列表底部的最新日期以及列表底部的最新价格列出的相应价格中?
答案 0 :(得分:12)
如果您只想颠倒数据框中行的顺序,可以执行以下操作:
df<- df[seq(dim(df)[1],1),]
答案 1 :(得分:8)
为了完整起见。实际上没有必要在这里拨打seq
。您可以使用:
- R逻辑:
### 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
答案 2 :(得分:5)
另一种tidyverse
解决方案,我认为最简单的解决方案是:
df %>% map_df(rev)
或仅使用purrr::map_df
,我们就可以map_df(df, rev)
。
答案 3 :(得分:3)
这是OP关于如何反转行顺序的问题的dplyr
(tidyverse
)解决方案。
假设数据帧称为df
,那么我们可以这样做:
df %>% arrange(rev(rownames(.)))
说明:“。”占位符将管道数据帧作为输入。然后rownames(df)
成为索引1:nrow(df)
的向量。 rev
颠倒顺序,arrange
相应地对df
重新排序。
在没有管道的情况下,以下操作相同:
arrange(df, rev(rownames(df)))
如果OP首先按照注释中的描述将其日期转换为Date
或POSIX
格式,那么他当然可以简单地使用df %>% arrange(Date)
。
但是第一种方法是回答OP的问题。
答案 4 :(得分:2)
另一个tidyverse
解决方案是:
df %>% arrange(desc(row_number()))
答案 5 :(得分:1)
另一种选择是按照要对其排序的向量对列表进行排序,
> 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
答案 6 :(得分:0)
如果要在base 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
的情况下都会出现问题。 ,这就是为什么我们使用 , drop = FALSE
)。
答案 7 :(得分:-1)
如果要坚持使用基数R,也可以使用lapply()
。
do.call(cbind, lapply(df, rev))