user9369411
user9369411

Reputation: 29

How to sort dataframe in descending order

I have a data.frame(v1,v2,y)

v1: 1 5 8 6 1 1 6 8

v2: 2 6 9 8 4 5 2 3

y: 1 1 2 2 3 3 4 4 

and now I want it sorted by y like this:

y: 1 2 3 4 1 2 3 4

v1: 1 8 1 6 5 6 1 8

v2: 2 9 4 2 6 8 5 3

I tried:

sorted <- df[,,sort(df$y)] 

but this does not work.. please help

Upvotes: 1

Views: 192

Answers (4)

jogo
jogo

Reputation: 12559

You can use matrix() to reorder the indizes of the rows:

df <- data.frame(v1 = c(1, 5, 8, 6, 1, 1, 6, 8), 
                 v2 = c(2, 6, 9, 8, 4, 5, 2, 3), 
                 y = c(1, 1, 2, 2, 3, 3, 4, 4))
df[c(matrix(1:nrow(df), ncol=2, byrow=TRUE)),]
#   v1 v2 y
# 1  1  2 1
# 3  8  9 2
# 5  1  4 3
# 7  6  2 4
# 2  5  6 1
# 4  6  8 2
# 6  1  5 3
# 8  8  3 4

The solution uses the property in which order the elements of the matrix are stored (in R it is like in FORTRAN) - the index of the first dimension is running first. In FORTRAN one uses the terminus leading dimension for the number of values for this first dimension (for a 2-dimensional array, i.e. a matrix, it is the number of rows).

Upvotes: 1

h3rm4n
h3rm4n

Reputation: 4187

You could also do alternating subset twice and rbind these together:

rbind(df[c(TRUE,FALSE),], df[c(FALSE,TRUE),])

The result:

  v1 v2 y
1  1  2 1
3  8  9 2
5  1  4 3
7  6  2 4
2  5  6 1
4  6  8 2
6  1  5 3
8  8  3 4

Upvotes: 1

akrun
akrun

Reputation: 887118

We can use ave from base R to create a sequence by 'y' group and order on it

df[order(with(df, ave(y, y, FUN = seq_along))),]
#  v1 v2 y
#1  1  2 1
#3  8  9 2
#5  1  4 3
#7  6  2 4
#2  5  6 1
#4  6  8 2
#6  1  5 3
#8  8  3 4

data

df <- data.frame(v1 = c(1, 5, 8, 6, 1, 1, 6, 8), 
                  v2 = c(2, 6, 9, 8, 4, 5, 2, 3), 
                  y = c(1, 1, 2, 2, 3, 3, 4, 4))

Upvotes: 2

Roman
Roman

Reputation: 17648

You can try a tidyverse solution

library(tidyverse)
data.frame(y, v1, v2) %>% 
  group_by(y) %>% 
  mutate(n=1:n()) %>% 
  arrange(n, y) %>% 
  select(-n) %>% 
  ungroup()
# A tibble: 8 x 3
      y    v1    v2
  <dbl> <dbl> <dbl>
1     1     1     2
2     2     8     9
3     3     1     4
4     4     6     2
5     1     5     6
6     2     6     8
7     3     1     5
8     4     8     3

data:

v1 <- c(1, 5, 8, 6, 1, 1, 6, 8)
v2<- c( 2, 6, 9, 8, 4, 5, 2, 3)
y<- c(1, 1, 2, 2, 3, 3, 4, 4 )

Idea is to add an index along y and then arrange by the index and y.

Upvotes: 3

Related Questions