How to sort putting NAs first in dplyr? [duplicate

2020-04-10 02:37发布

问题:

Consider the following example:

require(tibble)
require(dplyr)

set.seed(42)

tbl <- data_frame(id = letters[1:10], val = c(runif(5), NA, runif(4)))

tbl
# A tibble: 10 × 2
      id          val
   <chr>        <dbl>
1      a 0.9148060435
2      b 0.9370754133
3      c 0.2861395348
4      d 0.8304476261
5      e 0.6417455189
6      f           NA
7      g 0.5190959491
8      h 0.7365883146
9      i 0.1346665972
10     j 0.6569922904

I want to sort the tibble by val, putting NAs first:

tbl %>%
  arrange(val)
# A tibble: 10 × 2
      id          val
   <chr>        <dbl>
1      i 0.1346665972
2      c 0.2861395348
3      g 0.5190959491
4      e 0.6417455189
5      j 0.6569922904
6      h 0.7365883146
7      d 0.8304476261
8      a 0.9148060435
9      b 0.9370754133
10     f           NA

Unfortunately, the NAs are put last by arrange.

The best hack I found so far is combining slice with good old order:

tbl %>%
  slice(order(.$val, na.last = FALSE))
# A tibble: 10 × 2
      id          val
   <chr>        <dbl>
1      f           NA
2      i 0.1346665972
3      c 0.2861395348
4      g 0.5190959491
5      e 0.6417455189
6      j 0.6569922904
7      h 0.7365883146
8      d 0.8304476261
9      a 0.9148060435
10     b 0.9370754133

What's the dplyr way to get the above result?

回答1:

We can arrange on the logical vector first before arranging the 'val' column

tbl %>%
   arrange(!is.na(val), val)
# A tibble: 10 × 2
#      id       val
#   <chr>     <dbl>
#1      f        NA
#2      i 0.1346666
#3      c 0.2861395
#4      g 0.5190959
#5      e 0.6417455
#6      j 0.6569923
#7      h 0.7365883
#8      d 0.8304476
#9      a 0.9148060
#10     b 0.9370754