web-dev-qa-db-fra.com

filtrage data.frame basé sur row_number ()

MISE À JOUR: dplyr a été mis à jour depuis que cette question a été posée et fonctionne désormais comme l'OP le souhaitait

J'essaie d'obtenir la deuxième à la septième ligne dans un data.frame en utilisant dplyr.

Je fais ça:

require(dplyr)
df <- data.frame(id = 1:10, var = runif(10))
df <- df %>% filter(row_number() <= 7, row_number() >= 2)

Mais cela jette une erreur.

Error in rank(x, ties.method = "first") : 
  argument "x" is missing, with no default

Je sais que je pourrais facilement faire:

df <- df %>% mutate(rn = row_number()) %>% filter(rn <= 7, rn >= 2)

Mais je voudrais comprendre pourquoi mon premier essai ne fonctionne pas.

37
Daniel Falbel

En fait, la fonction slice de dplyr est faite pour ce type de sous-ensemble:

df %>% slice(2:7)

(Je suis un peu en retard à la fête mais j'ai pensé que j'ajouterais ceci pour les futurs lecteurs)

76
docendo discimus

La fonction row_number() ne renvoie pas simplement le numéro de ligne de chaque élément et ne peut donc pas être utilisée comme vous le souhaitez:

• ‘row_number’: équivalent à ‘rank (ties.method =" first ")"

Vous ne dites pas réellement ce que vous voulez que le row_number De. Dans ton cas:

df %>% filter(row_number(id) <= 7, row_number(id) >= 2)

fonctionne parce que id est trié et donc row_number(id) est 1:10. Je ne sais pas ce que row_number() évalue dans ce contexte, mais quand il est appelé une deuxième fois dplyr a manqué de choses pour le nourrir et vous obtenez l'équivalent de:

> row_number()
Error in rank(x, ties.method = "first") : 
  argument "x" is missing, with no default

Voilà votre erreur.

Quoi qu'il en soit, c'est pas la façon de sélectionner des lignes.

Vous avez simplement besoin d'indexer df[2:7,], Ou si vous insistez sur les tuyaux partout:

> df %>% "["(.,2:7,)
  id        var
2  2 0.52352994
3  3 0.02994982
4  4 0.90074801
5  5 0.68935493
6  6 0.57012344
7  7 0.01489950
28
Spacedman

Voici une autre façon de faire un filtrage basé sur le numéro de ligne dans un pipeline.

    df <- data.frame(id = 1:10, var = runif(10))

    df %>% .[2:7,]

    > id     var
      2  2 0.28817
      3  3 0.56672
      4  4 0.96610
      5  5 0.74772
      6  6 0.75091
      7  7 0.05165
7
dabsingh