web-dev-qa-db-fra.com

Utilisez le filtre dans dplyr conditionnel à une instruction if dans R

Permettez-moi de vous donner un exemple de ce que j'essaie de faire, car le titre peut ne pas être aussi clair que je le souhaiterais. Cela n'a pas de code reproductible, mais je peux ajouter un exemple reproductible si cela peut aider:

library(dplyr)
if(this_team != "") {
  newdf <- mydf %>%    
      filter(team == this_team) %>%
      mutate(totalrows = nrow(.)) %>%
      group_by(x1, y1) %>%
      summarize(dosomestuff)
} else {
  newdf <- mydf %>%    
      filter(firstname == this_name & lastname == that_name) %>%
      mutate(totalrows = nrow(.)) %>%
      group_by(x1, y1) %>%
      summarize(dosomestuff)
}

Je crée une fonction dans R qui effectue certaines manipulations de données sur le cadre de données mydf. Si je passe une valeur au paramètre nom_équipe de la fonction, je souhaite alors filtrer le cadre de données à l'aide de la colonne 'équipe'. Si je ne passe pas de valeur au paramètre nom_équipe .__, le paramètre par défaut est "" et je transmets plutôt les valeurs pour this_name et this_name, qui correspondent aux colonnes "prénom" et "nom" dans mydf.

Existe-t-il une meilleure façon de procéder, plutôt que de devoir créer à nouveau tout le pipeline Dplyr dans deux instructions distinctes? Mon pipeline de code actuel est bien plus long que 4 lignes. Il est donc frustrant de devoir reproduire un code comme celui-ci.

3
Canovice

Vous pourriez faire

library(dplyr)
y <- ""
data.frame(x = 1:5) %>% 
  {if (y=="") filter(., x>3) else filter(., x<3)} %>% 
  tail(1)

ou

data.frame(x = 1:5) %>% 
 filter(if (y=="") x>3 else x<3) %>%  
  tail(1)

ou même stocker votre pipe dans les veines de

mypipe <- . %>% tail(1) %>% print
data.frame(x = 1:5) %>% mypipe
10
lukeA

Voir si le code ci-dessous fonctionne, où nous insérons la condition if-else dans l'instruction filter. Cela a du sens parce que la dernière instruction accepte une instruction logique en tant qu'entrée - nous utilisons simplement la première pour contrôler la valeur de l'entrée.

library(dplyr)

newdf <- mydf %>%    
  filter(
    if (this_team != "") {
      team == this_team
    } else {
      firstname == this_name & lastname == that_name
    }
  ) %>%
  mutate(totalrows = nrow(.)) %>%
  group_by(x1, y1) %>%
  summarize(dosomestuff)
1
Anonymous