简体   繁体   中英

Ordering data in specific order in R

Let's say i have the following data.frame;

NUM   status  name
 1       +       A
 2       +       A
 3       +       B 
 4       -       A
 5       -       A 
 6       +       C 
 7       -       C 
 8       +       A
 9       -       B
 10      -       A 

How can I order them like this;

NUM   status  name
 1       +       A
 4       -       A    
 2       +       A
 5       -       A 
 8       +       A   
 10      -       A 
 3       +       B 
 9       -       B
 6       +       C 
 7       -       C 

I want to order them firstly by name. Then by status. But I need to order status in this pattern; +,-,+,- Thanks in advance.

You can do this in base R:

df <- df[with(df,order(status,name)),
         ][c(nrow(df)/2,0)+rep(1:(nrow(df)/2),each=2),]
#     NUM status name
# 1    1      +    A
# 4    4      -    A
# 2    2      +    A
# 5    5      -    A
# 8    8      +    A
# 10  10      -    A
# 3    3      +    B
# 9    9      -    B
# 6    6      +    C
# 7    7      -    C

We can using row_number with dplyr group_by create a help key to achieve the certain order

df %>% 
  group_by(name,status) %>%
  mutate(Helpkey=row_number()) %>%
  arrange(name,Helpkey) %>%
  select(-Helpkey)

# A tibble: 10 x 3
# Groups:   name, status [6]
     NUM status  name
   <int>  <chr> <chr>
 1     1      +     A
 2     4      -     A
 3     2      +     A
 4     5      -     A
 5     8      +     A
 6    10      -     A
 7     3      +     B
 8     9      -     B
 9     6      +     C
10     7      -     C

You can order by name , then by the number of times the given name, status pair has occurred.

library(data.table)
setDT(df)

df[order(name, rowid(name, status))]

#     NUM status name
#  1:   1      +    A
#  2:   4      -    A
#  3:   2      +    A
#  4:   5      -    A
#  5:   8      +    A
#  6:  10      -    A
#  7:   3      +    B
#  8:   9      -    B
#  9:   6      +    C
# 10:   7      -    C

Data used:

df <- fread("
NUM   status  name
 1       +       A
 2       +       A
 3       +       B 
 4       -       A
 5       -       A 
 6       +       C 
 7       -       C 
 8       +       A
 9       -       B
 10      -       A 
")

The data.table approach:

library(data.table)

csv <- "
NUM   status  name
 1       +       A
 2       +       A
 3       +       B 
 4       -       A
 5       -       A 
 6       +       C 
 7       -       C 
 8       +       A
 9       -       B
 10      -       A
"

data <- fread(csv)
data[, id := seq_len(.N), by = .(name, status)]
data[order(name, id), .(NUM, status, name)]

    NUM status name
 1:   1      +    A
 2:   4      -    A
 3:   2      +    A
 4:   5      -    A
 5:   8      +    A
 6:  10      -    A
 7:   3      +    B
 8:   9      -    B
 9:   6      +    C
10:   7      -    C

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM