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 :

Colonne et dataframe en argument de fonction


Sujet :

R

  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2016
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2016
    Messages : 12
    Par défaut Colonne et dataframe en argument de fonction
    Bonsoir,
    Voici un soucis que je traine depuis trop longtemps, je n'arrive pas à créer des fonctions propres comme on en trouve dans les packages, notamment lorsqu'il s'agit d'utiliser des données contenues dans un dataframe.

    Par exemple, tout bête, trouver le maximum d'une colonne d'un dataframe, je trouve par-ci par là des exemples mais aucun ne marche chez moi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    df <- data.frame(A=1:10, B=2:11, C=3:12)
     
    fun1 <- function(x, column){
      return(max(x[,column]))
    }
    fun1(df,A)
    Et en réponse :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Error in `[.data.frame`(x, , column) : objet 'A' introuvable
    Une idée?
    Merci!

  2. #2
    Membre émérite
    Homme Profil pro
    Chercheur
    Inscrit en
    Décembre 2015
    Messages
    327
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2015
    Messages : 327
    Par défaut
    Le A que tu passes dans la fonction est un objet non défini dans l'environnement d'appel de la fonction et la fonction ne cherche pas à l'évaluer dans l'environnement de x (data.frame passé à la fonction). Soit tu appelles la fonction par fun1( df, "A"), soit tu écris :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    A <- "A"
    fun1( df, A)
    soit tu modifies le corps de la fonction pour évaluer l'objet A dans l'environnement de x. Pour voir comment faire, regarde le code de la fonction subset pour les data.frame (base:::subset.data.frame) et vois comment est évalué l'argument select.
    Tu peux aussi écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fun1 <- function(x, column){ max( subset( x, select=column))}

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2016
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2016
    Messages : 12
    Par défaut
    Ok super merci, en effet cela marche bien mieux comme cela !
    J'ai du mal à trouver de la bonne documentation pour passer du script classique à une fonction, il semblerait que pas mal de choses ne sont pas transposables en l'état, par exemple pour ajouter une nouvelle colonne au dataset :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    df <- data.frame(A=1:10, B=2:11, C=3:12)
     
    fun1 <- function(x, column1, column2){
      x[,new] <- paste(x[,column1], x[,column2], sep = ":")
      return(x)
    }
     
    df <- fun1(df,"A","B")
    Sur certaines données, tout reste bloqué avec un message d'erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    “Incorrect number of dimensions”
    Du coup, il faut que j'enlève la virgule
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    paste(x[column1], x[column2], sep = ":")
    Merci merci !

  4. #4
    Membre émérite
    Homme Profil pro
    Chercheur
    Inscrit en
    Décembre 2015
    Messages
    327
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2015
    Messages : 327
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    fun1 <- function(x, column1, column2){
      x[,new] <- paste(x[,column1], x[,column2], sep = ":")
      return(x)
    }
    Dans la fonction, la valeur de la variable new n'est pas définie. Il y a donc un problème dans ce code. J'ai l'impression que la différence entre le nom d'une variable et la valeur de cette même variable n'est pas claire pour toi.

    Quant à sa solution d'enlever les virgules, as-tu regardé le résultat obtenu ? Je serai étonné que ce soit celui auquel tu t'attends.

  5. #5
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2016
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2016
    Messages : 12
    Par défaut
    Merci faubry de l'aide précieuse. Je sais que la variable n'est pas définie, car le but de la fonction est justement de la créer (entre autre...). Et c'est en ce sens que je dis que la mise en 'function' est plus délicate qu'un script où l'on peut créer à la volée des nouvelles variables dans un dataframe juste avec df$new <- blabla...

    Voici un code qui illustre mon point de blocage :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    df <- data.frame(A=1:10, B=2:11)
     
    fun <- function(dataset, var, var2){
      x <- paste(dataset[,var], dataset[,var2], sep=":")
      return(x)
    }
    fun(dataset="df", var="A", var2="B")
    Alors que ça, ça marche à merveille :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    x <- paste(df$A, df$B, sep=":")
    Merci encore!

  6. #6
    Modératrice

    Femme Profil pro
    Statisticienne, Fondatrice de la société DACTA
    Inscrit en
    Juin 2010
    Messages
    893
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Statisticienne, Fondatrice de la société DACTA

    Informations forums :
    Inscription : Juin 2010
    Messages : 893
    Par défaut
    Bonjour,

    Est-ce que le code ci-dessous donne ce que vous souhaitez ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    df <- data.frame(A=1:10, B=2:11)
     
    fun <- function(dataset, var, var2){
      x <- paste(dataset[,var], dataset[,var2], sep=":")
      return(x)
    }
     
    fun(dataset=df, var="A", var2="B")
    > J'ai juste supprimé les quotes autour du nom du paramètre dataset (df).

    Je pense que vous faîtes la confusion entre les variables contenant des valeurs, les noms de ces variables, etc.
    Si vous n'avez pas l'habitude de la programmation fonctionnelle, c'est effectivement un coup de main à prendre. Mais ça faut le coup de persévérer, car c'est bien pratique

    Bonne continuation !


    Cordialement,


    A.D.

    Forum R
    Fournir le code utilisé (pensez aux balises code !), les packages nécessaires, ainsi qu'un court mais représentatif extrait du jeu de données et les éventuels messages d'erreur.
    Recherche d'informations concernant R : RSiteSearch / tutoriels : http://r.developpez.com/cours/ .

    Pensez également au bouton "Résolu" et à voter (en bas à droite des messages) lorsque vous avez obtenu une réponse satisfaisante.

  7. #7
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2016
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2016
    Messages : 12
    Par défaut
    Super merci, cela fonctionne au poil!
    En effet lors de la mise sous forme de fonction, les habitudes prisent dans les scripts classiques (souvent mauvaises pour ma part), ne fonctionnent pas! Et juste une mini-dernière chose, pour insérer le résultat dans une variable du dataframe traité, comment cela se passe? Car en gros, je cherche à concaténer deux variables dans une troisième (une nouvelle donc), puis faire de même sur un second dataset pour ensuite faire un 'join' avec comme argument le nom des deux variables crées (qui servent pour lier les bonnes lignes ensemble).

    Encore un grand merci, faubry et A.D. !

  8. #8
    Membre émérite
    Homme Profil pro
    Chercheur
    Inscrit en
    Décembre 2015
    Messages
    327
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2015
    Messages : 327
    Par défaut
    Pour terminer, rien ne t'empêche d'écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    df$new <- fun(dataset=df, var="A", var2="B")

  9. #9
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2016
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2016
    Messages : 12
    Par défaut
    Oui mais cela suppose qu'il faut passer par une fonction intermédiaire, et il faut sortir de la fonction pour faire un "df$new <-". L'idée ici est vraiment d'avoir tout sous forme d'une fonction pour l'ajouter à un package (car rajouter la colonne, c'est juste 1% de ce que doit faire la fonction et c'est juste une variable de travail).
    En bidouillant, j'arrive à créer un vecteur et l'utiliser pour recréer un dataframe avec les anciennes variables sans quitter la fonction, je pense que je vais faire comme ça faute de mieux :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    df <- data.frame(A=1:10, B=2:11)
     
    fun <- function(dataset1, var, var2){
      y <- paste(dataset1[,var], dataset1[,var2], sep=":")
      NEW1 <- data.frame(y,dataset1[,var], dataset1[,var2])
      return(NEW1)
    }
     
    df2 <- fun(dataset1=df, var="A", var2="B")

  10. #10
    Membre émérite
    Homme Profil pro
    Chercheur
    Inscrit en
    Décembre 2015
    Messages
    327
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2015
    Messages : 327
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    fun <- function( dataset1, var, var2) {
      dataset1$y <- paste( dataset1[,var], dataset1[,var2], sep=":")
      return( dataset1)
    }
    fonctionne tout aussi bien. Une autre solution peut aussi être d'utiliser la fonction transform :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    df <- transform( df, y=paste( A, B, sep=":"))

  11. #11
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2016
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2016
    Messages : 12
    Par défaut
    Finalement la fonction transform règle tout mes soucis, car même si ça marche sur le petit jeu de donnée, la solution paste ne fonctionne pas en condition réelle sans savoir pourquoi! Merci à vous deux !

    Edit : Tout bien réfléchi, je pense avoir trouver la subtilité... Lorsque les variables Y d'un dataframe X sont donnés en arguments, elles doivent être appelées par X[,Y]. Mais si l'on veut travailler sur une variable du dataframe X non renseignée en argument (déjà existante ou non), il faut alors l'appeler par X$Y. Il en va de même pour les variables et les dataframes créés dans la fonction, ils doivent être appelé par X$Y.
    Ma découverte parait peut-être un peu couillonne mais savoir ça m'aurai éviter bien des tracas et de la perte de temps

  12. #12
    Membre émérite
    Homme Profil pro
    Chercheur
    Inscrit en
    Décembre 2015
    Messages
    327
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2015
    Messages : 327
    Par défaut
    Dans ton cas, X$Y et X[,"Y"] donnent le même résultat, c'est-à-dire un vecteur. La différence est que dans le premier cas, X$Y représente un chemin d'accès à une variable, c'est-à-dire que cela peut être interprété par "accéder à l'objet dont le nom est Y dans l'environnement de l'objet de nom X" comme pour les fichiers ou les adresses web (file:/X/Y ou http:/X/Y), tandis que dans le second cas, il s'agit de récupérer la valeur de la colonne de nom Y, ou d'indice Y, dans le tableau (matrice ou data.frame) de nom X. Le second appel nécessite une structure tabulaire tandis que le premier cas est utilisable dans une structure de liste et l'objet référencé peut être aussi une liste. De plus, dans le second cas, il s'agit d'une chaine de caractères puisqu'on fait référence aux noms de colonnes. On a aussi l'équivalence entre X[,"Y"], X[,which( names( X) == "Y")] et X[,names( X) == "Y"]. Cette seconde écriture permet aussi d'écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    var.Y <- "Y"
    res <- X[,var.Y]
    donc de pouvoir modifier dynamiquement la colonne d'intérêt, ce que ne permet pas la première écriture.

  13. #13
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2016
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2016
    Messages : 12
    Par défaut
    Dans ton cas, X$Y et X[,"Y"] donnent le même résultat
    Oui parceque tous sont notifiés en arguments de la fonction. Une partie de ma fonction utilise des variables non notifiées en arguments.

    Ne fonctionne pas:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    df <- data.frame(A=1:10, B=2:11, C=3:12)
     
    fun1 <- function(x, column1, column2){
      x$y <- paste(x[,column1], x[,column2],x[,column3], sep = ":")
      return(x)
    }
     
    df <- fun1(df,"A","B")
    Mais ça, ça fonctionne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    df <- data.frame(A=1:10, B=2:11, C=3:12)
     
    fun1 <- function(x, column1, column2){
      x$y <- paste(x[,column1], x[,column2],x$C, sep = ":")
      return(x)
    }
     
    df <- fun1(df,"A","B")

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

Discussions similaires

  1. Réponses: 13
    Dernier message: 07/05/2006, 11h54
  2. Espace dans les arguments de fonction
    Par black is beautiful dans le forum Windows
    Réponses: 2
    Dernier message: 11/03/2006, 12h06
  3. [JAVASCRIPT] passage d'argument à une fonction
    Par LE NEINDRE dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 03/06/2005, 18h17
  4. vector<bool> comme argument de fonction
    Par Krishna dans le forum SL & STL
    Réponses: 11
    Dernier message: 09/09/2004, 08h30
  5. Passer une fonction comme argument à une fonction
    Par Cocotier974 dans le forum Général Python
    Réponses: 4
    Dernier message: 29/06/2004, 13h41

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