IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

R Discussion :

boucle for avec case_when


Sujet :

R

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2019
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2019
    Messages : 17
    Points : 14
    Points
    14
    Par défaut boucle for avec case_when
    Bonjour à tous,

    je cherche à faire une boucle for pour recoder plusieurs variables : lorsque l'info de "test" est manquante, alors prendre l'info de "test.v1".

    le dataframe ressemble à ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    test1 <- c("A","B","A","A",NA,"B","A",NA,"A")
    test1.v1 <- c("B",NA,"B","B","A","B","B",NA,"A") 
    test2 <- c("B","B","B","B",NA,"C","C","C","C")
    test2.v1 <- c("C",NA,"A","A","B","B","C",NA,"C") 
    test3 <- c("A","B","B","B",NA,"C","C",NA,"C")
    test3.v1 <- c("B","A","B",NA,"A","A","A","A",NA) 
    test4 <- c(NA,"B","B","A",NA,"B","A",NA,"A")
    test4.v1 <- c("B","B","B","A","A","B","B","B","B") 
    df1 <- data.frame(test1,test1.v1,test2,test2.v1,test3,test3.v1,test4,test4.v1)
    Ça m'avait l'air très simple à faire, mais je n'arrive pas du tout à m'en sortir :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
      VEC_1 <- c("test1","test2","test3","test4","test5","test6","test7","test8","test9")
      VEC_2 <- c("test1.v1","test2.v1","test3.v1","test4.v1","test5.v1","test6.v1","test7.v1","test8.v1","test9.v1") 
     
      for (i in 1:(min(length(VEC_1), length(VEC_2)))){
        df2 <- df1 %>%
        mutate(
          VEC_1[i] = case_when(
            is.na(VEC_1[i]) & !is.na(VEC_2[i]) ~ VEC_2[i],
            TRUE ~ VEC_1[i]))}
    j'ai cette erreur qui apparaît, est-ce que la boucle for ne s'utilise pas avec un case_when ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Erreur : '=' inattendu(e) in:
    "    mutate(
          VEC_1[i] ="
    Merci !

  2. #2
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Janvier 2006
    Messages
    476
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Corse (Corse)

    Informations forums :
    Inscription : Janvier 2006
    Messages : 476
    Points : 831
    Points
    831
    Par défaut
    bonjour,
    en mettant VEC_1[i] on n' "utilise" pas par exemple la colonne test1 mais la chaine de caractère "test1"
    il faut "transformer" la chaine de caractère en nom de colonne (grâce package rlang) en utilisant !!sym() et l'operateur :=

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    test1 <- c("A","B","A","A",NA,"B","A",NA,"A")
    test1.v1 <- c("B",NA,"B","B","A","B","B",NA,"A") 
    test2 <- c("B","B","B","B",NA,"C","C","C","C")
    test2.v1 <- c("C",NA,"A","A","B","B","C",NA,"C") 
    test3 <- c("A","B","B","B",NA,"C","C",NA,"C")
    test3.v1 <- c("B","A","B",NA,"A","A","A","A",NA) 
    test4 <- c(NA,"B","B","A",NA,"B","A",NA,"A")
    test4.v1 <- c("B","B","B","A","A","B","B","B","B") 
    df1 <- data.frame(test1,test1.v1,test2,test2.v1,test3,test3.v1,test4,test4.v1)
     
    ##j'ai mis a jour les 2 vecteurs avec uniquement  les noms de col de df1 pour éviter erreur dans la boucle
    VEC_1 <- c("test1","test2","test3","test4") #,"test5","test6","test7","test8","test9")
    VEC_2 <- c("test1.v1","test2.v1","test3.v1","test4.v1")#,"test5.v1","test6.v1","test7.v1","test8.v1","test9.v1") 
     
    df2 <- df1 ## j'initalise df2 car autrement si on fait ds la boucle df2<-df1, à chaque passage on perd les changements précédents
    for (i in 1:(min(length(VEC_1), length(VEC_2)))){
     df2 <- df2 %>%
        mutate(
        !!sym ( VEC_1[i]) := case_when(
            is.na(!!sym ( VEC_1[i])) & !is.na( !!sym ( VEC_2[i])) ~  !!sym ( VEC_2[i]),
            TRUE ~  !!sym ( VEC_1[i])))
        }
     
    ## autrement  on peut faire (la fonction cur_column() fait référence à la colonne courante ,ce qui permet d'accéder à la colonne suivante( par ex test1.vi)
    df3 <-df1 %>%  mutate(across(-matches("v"), ~ifelse(is.na(.) & !is.na(df1[,which(colnames(df1)==cur_column())+1]), df1[,which(colnames(df1)==cur_column())+1],.)))
    setequal(df2,df3) # TRUE

    mais si quelqu'un a une solution plus simple je serai preneur
    cldt

  3. #3
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2019
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2019
    Messages : 17
    Points : 14
    Points
    14
    Par défaut
    Bonjour,

    merci beaucoup pour cette réponse, j'ai utilisé un peu naïvement "VEC_1[i]" en pensant que ça fonctionnerait mais c'est clairement plus complexe.. J'ai essayé le code, mais il ne fonctionne pas, j'ai cette erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    <error/dplyr:::mutate_error>
    Error in `mutate()`:
    ! Problem while computing `test1 = case_when(...)`.
    Caused by error in `case_when()`:
    ---
    Backtrace:
     1. df2 %>% ...
     7. dplyr::case_when(...)
    La seconde méthode n'est pas vraiment applicable à mon jeu de donnée car il est beaucoup plus gros et pas "rangé" dans le bon ordre.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [VBA] Boucle "For" avec valeurs spécifiques
    Par NiKoTiNe dans le forum VBA Access
    Réponses: 6
    Dernier message: 10/11/2016, 15h20
  2. Boucle for avec saut
    Par michel71 dans le forum Delphi
    Réponses: 3
    Dernier message: 25/02/2007, 16h16
  3. boucle for avec condition
    Par Daniel Magron dans le forum Delphi
    Réponses: 4
    Dernier message: 22/01/2007, 16h18
  4. Réponses: 2
    Dernier message: 28/08/2006, 18h17
  5. [VB6] boucle for avec liste de valeur defini
    Par Morpheus2144 dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 06/04/2006, 18h12

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo