[英]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如何反轉行順序的問題的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的問題。
另一種選擇是按要排序的向量對列表進行排序,
> 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.