Как изменить порядок кадра данных в R

Я бесконечно искал это и почему-то не решил эту простую проблему.

У меня есть dataframe, называемый Цены, в котором есть 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 цены. Как я могу сохранить свой вывод с последней датой в нижней части списка и соответствующими ценами, указанными по последним ценам в нижней части списка?

Ответ 1

Если вы просто хотите изменить порядок строк в фрейме данных, вы можете сделать следующее:

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

Ответ 2

Просто ради полноты. На самом деле здесь нет необходимости вызывать 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 года:

С точки зрения скорости, здесь мало причин использовать dplyr. Возможно, для 90% пользователей базовых функциональных возможностей R должно быть достаточно. Остальные 10% должны использовать dplyr для запросов к базе данных или перевода кода на другой язык.

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

Ответ 3

Другое решение tidyverse и я думаю, что самое простое:

df %>% map_df(rev)

или используя просто purrr::map_df мы можем сделать map_df(df, rev).

Ответ 4

Здесь dplyr (tidyverse) решение вопроса OP о том, как изменить порядок строк.

Предполагая, что фрейм данных называется df, тогда мы можем сделать:

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

Пояснение: "." заполнитель принимает в качестве фрейма введенный фрейм данных. Тогда rownames(df) становятся вектором индексов, 1:nrow(df). rev изменяет порядок и arrange переупорядочивает df соответственно.

Без трубы следующее делает то же самое:

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

Если ОП сначала преобразовал бы свои даты в формат Date или POSIX, как описано в комментариях, то он, конечно, мог бы просто использовать df %>% arrange(Date).

Но первый метод - это то, что отвечает на вопрос ОП.

Ответ 5

Если вы хотите придерживаться базы R, вы также можете использовать lapply().

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