web-dev-qa-db-fra.com

fonction dplyr arrange () trie par valeurs manquantes

J'essaie de travailler avec R pour Data Science de Hadley Wickham et je suis tombé sur la question suivante: "Comment pourriez-vous utiliser arrange () pour trier toutes les valeurs manquantes au début? (Conseil: utilisez is.na () ) " J'utilise les vols ensembles de données inclus dans le package nycflights13 . Etant donné que arrange () trie toutes les valeurs inconnues au bas de la trame de données, je ne sais pas comment on ferait l'inverse pour les valeurs manquantes de toutes les variables. Je me rends compte que l'on peut répondre à cette question avec le code de base R, mais je m'intéresse particulièrement à la procédure à suivre à l'aide de dplyr et d'un appel aux fonctions arrange () et is.na (). Merci.

8
T. Gross

Nous pouvons l'envelopper avec desc pour obtenir les valeurs manquantes au début

flights %>% 
    arrange(desc(is.na(dep_time)),
           desc(is.na(dep_delay)),
           desc(is.na(arr_time)), 
           desc(is.na(arr_delay)),
           desc(is.na(tailnum)),
           desc(is.na(air_time)))

Les valeurs NA n’ont été trouvées que dans ces variables basées sur 

names(flights)[colSums(is.na(flights)) >0]
#[1] "dep_time"  "dep_delay" "arr_time"  "arr_delay" "tailnum"   "air_time" 

Au lieu de transmettre chaque nom de variable à la fois, nous pouvons également utiliser NSE arrange_

nm1 <- paste0("desc(is.na(", names(flights)[colSums(is.na(flights)) >0], "))")

r1 <- flights %>%
        arrange_(.dots = nm1) 

r1 %>%
   head()
#year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time arr_delay carrier flight tailnum
#  <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>     <dbl>   <chr>  <int>   <chr>
#1  2013     1     2       NA           1545        NA       NA           1910        NA      AA    133    <NA>
#2  2013     1     2       NA           1601        NA       NA           1735        NA      UA    623    <NA>
#3  2013     1     3       NA            857        NA       NA           1209        NA      UA    714    <NA>
#4  2013     1     3       NA            645        NA       NA            952        NA      UA    719    <NA>
#5  2013     1     4       NA            845        NA       NA           1015        NA      9E   3405    <NA>
#6  2013     1     4       NA           1830        NA       NA           2044        NA      9E   3716    <NA>
#Variables not shown: Origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>, minute <dbl>,
#  time_hour <time>.

Mettre à jour

Avec les nouvelles versions de tidyverse (dplyr_0.7.3, rlang_0.1.2), nous pouvons également utiliser arrange_at, arrange_all, arrange_if

nm1 <- names(flights)[colSums(is.na(flights)) >0]
r2 <- flights %>% 
          arrange_at(vars(nm1), funs(desc(is.na(.))))

Ou utilisez arrange_if

f <- rlang::as_function(~ any(is.na(.)))
r3 <- flights %>% 
          arrange_if(f, funs(desc(is.na(.))))


identical(r1, r2)
#[1] TRUE

identical(r1, r3)
#[1] TRUE
7
akrun

Essayez de la manière la plus simple, ce qu'il vient de vous montrer:

arrange(flights, desc(is.na(dep_time)))

Les autres raccourcis de Nice:

arrange(flights, !is.na(dep_time))

ou

arrange(flights, -is.na(dep_time))
2
Arkadiusz Choczaj

Ce qui suit classe les lignes par ordre décroissant en fonction du nombre de NAs:

flights %>% 
    arrange(desc(rowSums(is.na(.))))

    # A tibble: 336,776 × 19
    year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
   <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
1   2013     1     2       NA           1545        NA       NA           1910
2   2013     1     2       NA           1601        NA       NA           1735
3   2013     1     3       NA            857        NA       NA           1209
4   2013     1     3       NA            645        NA       NA            952
5   2013     1     4       NA            845        NA       NA           1015
6   2013     1     4       NA           1830        NA       NA           2044
7   2013     1     5       NA            840        NA       NA           1001
8   2013     1     7       NA            820        NA       NA            958
9   2013     1     8       NA           1645        NA       NA           1838
10  2013     1     9       NA            755        NA       NA           1012
# ... with 336,766 more rows, and 11 more variables: arr_delay <dbl>, carrier <chr>,
#   flight <int>, tailnum <chr>, Origin <chr>, dest <chr>, air_time <dbl>,
#   distance <dbl>, hour <dbl>, minute <dbl>, time_hour <dttm>
2
Frederick Solt

La solution de @akrun fonctionne bien. Cependant, arrange_ est obsolète pour les versions SE des verbes principaux. pour l'éviter, nous pouvons utiliser eval

nmf <- names(flights)[colSums(is.na(flights)) > 0]
rules = paste0("!is.na(", nmf, ")")
rc <- paste(rules, collapse = ",")
arce <-  paste("arrange(flights," , rc , ")")
expr <- parse(text = arce)
ret <- eval(expr)
0
Endle_Zhenbo