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 :

Récupération d'indices


Sujet :

R

  1. #1
    Membre du Club
    Homme Profil pro
    Ingénieur
    Inscrit en
    Avril 2014
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2014
    Messages : 59
    Points : 60
    Points
    60
    Par défaut Récupération d'indices
    Bonjour,
    Voici mon problème : j'ai une colonne d'un data.frame dont les valeurs ressemblent à ceci :
    0,0,0,0,0,0,0,1,5,10,15,18,19,0,0,0,0,0,0,1,2,5,9,7,10,11,12,0,0,0,0,0,0

    J'aimerais récupérer les indices de chaque commencement et chaque fin de série non égale à zéro.

    Mon but c'est ceci , j'ai 2 colonnes
    par exemple

    15 0
    16 0
    16 0
    14 0
    13 2
    24 6
    10 5
    5 0
    4 0

    La deuxième colonne correspond à celle décrite plus haut. Je veux faire la moyenne de la première colonne sur chaque période ou la deuxième colonne n'est pas égale à zéro. Par exemple là ce serait mean(13,24,10).

    Je peux faire ceci en mettant plein de conditions et boucles, mais j'aimerais savoir si en R il n'y aurait pas une astuce....

    Quelqu'un a une idée ?

  2. #2
    Membre averti
    Homme Profil pro
    Data Scientist
    Inscrit en
    Août 2013
    Messages
    139
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Data Scientist
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2013
    Messages : 139
    Points : 316
    Points
    316
    Par défaut
    Alors un petit début d'idée rapide qui pourra certainement t'aider : essaye d'utiliser la commande which()

    En effet, si tu fais :
    Cela te retournera un vecteur avec les positions des éléments de colonne2 non nuls.

    Si tu fais :
    Tu récupères les éléments de colonne1 correspondant aux éléments non-nuls de colonne2.

    Regarde du coté de la fonction subset() peut-être aussi !

    Bon courage

  3. #3
    Membre régulier Avatar de Yoan73
    Homme Profil pro
    Inscrit en
    Septembre 2013
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Septembre 2013
    Messages : 21
    Points : 75
    Points
    75
    Par défaut
    Salut,

    Comme dit plus haut, la fonction "subset" peut répondre à ce genre de problèmes.


    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    > data
      col1 col2
    1   15    0
    2   16    0
    3   16    0
    4   14    2
    5   15    6
    6   12    7
    7   13    0
    8   15    2
    9    9    0
    On conserve seulement les lignes de "col2" différentes de 0 : subset(table,condition)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    > data2 <- subset(data, col2 != 0)
    > data2
      col1 col2
    4   14    2
    5   15    6
    6   12    7
    8   15    2
    Et on obtient le résultat souhaité sur nos données filtrées.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    > mean(data2$col1)
    [1] 14
    Voila, bonne journée,

    Yoan

  4. #4
    Membre du Club
    Homme Profil pro
    Ingénieur
    Inscrit en
    Avril 2014
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2014
    Messages : 59
    Points : 60
    Points
    60
    Par défaut
    Merci ça va peut être m'être utile cette fonction subset().

    Le problème c'est que j'ai plusieurs séries non égales à zéro dans la même colonne et une moyenne doit être calculée pour chaque série.

    par exemple:
    col2
    0
    0
    0
    0
    5
    2
    1
    4
    0
    0
    0
    0
    4
    1
    2
    3
    0
    0
    0

    Deux moyennes doivent être calculées
    En bidouillant avec subset et d'autres fonctions, ça doit être faisable. Après, mon but est de simplifier le code au mieux pour progresser en R

  5. #5
    Membre éclairé
    Homme Profil pro
    Ingénieur de recherche
    Inscrit en
    Janvier 2012
    Messages
    325
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur de recherche
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Janvier 2012
    Messages : 325
    Points : 888
    Points
    888
    Par défaut
    Je pense que tu n'as pas d'autre choix que de faire une boucle (for), les fonctions "préfabriquées" de R ne permettent pas, à ma connaissance, de faire des opérations sur des dataframes en tenant compte de l'ordre des lignes.

    Du coup je ferait un truc comme ça par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    df=data.frame(a=c(0,0,0,1,2,3,0,0,4,5,6,0,0))
    serie=1
    for(i in 1:length(df$a)){
        if(df$a[i] == 0){
            df$serie[i] = 0
        }else{
             if(i != 1 & df$a[i-1] == 0){serie = serie + 1}
            df$serie[i] = serie
        }
    }
    Et ensuite tu fait un aggregate sur la colonne "série".

  6. #6
    Membre régulier Avatar de Yoan73
    Homme Profil pro
    Inscrit en
    Septembre 2013
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Septembre 2013
    Messages : 21
    Points : 75
    Points
    75
    Par défaut
    Hello,

    dans ce cas, je te conseille de passer par la fonction tapply(VecteurDeDonnées, Filtre, Statistique)

    Pour ton exemple, je vais te détailler la façon dont on peut s'y prendre. Imaginons que l'on ait ces données.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    > data
      valeur serie
    1     15     1
    2     20     2
    3     10     3
    4     14     1
    5      7     3
    6      8     2
    On cherche à avoir une moyenne pour chacune des trois séries. Il convient donc de définir combien notre jeu de données à de séries et quel sont leur nom (ici c'est 1, 2 et 3 mais dans d'autres jeu de données, cela pourrait changer).

    Pour cela, un facteur est tout indiqué. Il permet de reconnaître toutes les valeurs différentes que contient la variable série. On va donc passer notre colonne série de "vecteur" à "facteur".

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    # série sous la forme d'un vecteur
    > data$serie
    [1] 1 2 3 1 3 2
     
    # série sous la forme d'un facteur
    > data$serie = as.factor(data$serie)
    > data$serie
    [1] 1 2 3 1 3 2
    Levels: 1 2 3
    L'information "levels" (ou niveaux) nous donne donc toutes les valeurs possibles de notre colonne.

    Il ne reste donc plus qu'à mettre en place notre fonction tapply.
    Elle prend en paramètre :
    - notre liste de notes
    - notre facteur avec ces niveaux
    - ce que l'on souhaite calculer

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    > tapply(data$valeur, data$serie, mean)
       1    2    3 
    14.5 14.0  8.5
    On obtient donc les 3 moyennes que l'on souhaitait avoir.

    EDIT :
    Il est possible de recoder (regrouper) les niveaux. Si par exemple, je veux calculer seulement 2 moyennes en regroupant les niveaux 2 et 3. Je voudrais avoir la moyenne de la série 1 ainsi que la moyenne de la série 2+3.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    # On recode les valeurs qui prennent 3 en 2
    > data$serie[data$serie == "3"] <- "2"
    # On exclu les niveaux inutilisés (ici le niveau 3)
    > data$serie<- factor(data$serie,exclude=NULL)
    On se retrouve donc avec un résultat différent.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    # le nouveau facteur à 2 niveaux
    > data$serie
    [1] 1 2 2 1 2 2
    Levels: 1 2
     
    #Le  nouveau calcul des moyennes
    > tapply(data$valeur, data$serie, mean)
        1     2 
    14.50 11.25
    La moyenne du niveau 1 ne change pas et c'est bien normal.
    La moyenne du niveau 2 prend en compte les quatre autres valeurs et donc sa valeur change en fonction de notre recodage

    Une image du tableau final pour comprendre le changement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    > data
      valeur serie
    1     15     1
    2     20     2
    3     10     2
    4     14     1
    5      7     2
    6      8     2
    Cordialement,

    Yoan

  7. #7
    Membre confirmé
    Inscrit en
    Mars 2013
    Messages
    208
    Détails du profil
    Informations forums :
    Inscription : Mars 2013
    Messages : 208
    Points : 461
    Points
    461
    Par défaut
    Citation Envoyé par mauriceletendu Voir le message
    Merci ça va peut être m'être utile cette fonction subset().

    Le problème c'est que j'ai plusieurs séries non égales à zéro dans la même colonne et une moyenne doit être calculée pour chaque série.

    Deux moyennes doivent être calculées
    En bidouillant avec subset et d'autres fonctions, ça doit être faisable. Après, mon but est de simplifier le code au mieux pour progresser en R
    Salut,
    Tu as bien raison d'essayer de le faire en vectoriel!

    Le problème ici n'est pas tant de calculer la moyenne, mais d'arriver à nommer tes séries, 1,2,3 etc... le tout sans faire de boucles!

    Une solution sympa en vectoriel:

    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
    
    #exemple : ici il y a trois séries de moyenne 2, 4 et 2.5
    x<-c(0,0,0,3,1,2,0,0,0,5,4,3,0,0,2,3)
    n<-length(x)
    
    #on récupère le premier indice non nul pour chaque serie
    x2<-c(x[1],as.numeric(x[2:n]!=0 & x[1:(n-1)]==0))
    > x2
     [1] 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 0
    #et on se rend compte qu'un cumsum de x2 conditionné par x!=0 revient à identifier le numéro de tes séries!
    > cumsum(x2)*(x!=0)
     [1] 0 0 0 1 1 1 0 0 0 2 2 2 0 0 3 3
    #il ne reste qu'à faire la moyenne
    > tapply(x,cumsum(x2)*(x!=0),mean)
      0   1   2   3 
    0.0 2.0 4.0 2.5 
    
    
    #le tout sans boucle! ;)

  8. #8
    Membre du Club
    Homme Profil pro
    Ingénieur
    Inscrit en
    Avril 2014
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2014
    Messages : 59
    Points : 60
    Points
    60
    Par défaut
    Merci pour ce code, je vais voir ça cet aprèm

Discussions similaires

  1. Problème de récupération d'indice dans une listbox
    Par MarieKisSlaJoue dans le forum ASP.NET
    Réponses: 13
    Dernier message: 28/02/2013, 13h18
  2. Récupération d'indice dans une cell
    Par kira9744 dans le forum MATLAB
    Réponses: 3
    Dernier message: 08/03/2011, 16h52
  3. Parcours de tableau et récupération d'indice associé
    Par orus8 dans le forum VB 6 et antérieur
    Réponses: 4
    Dernier message: 29/04/2008, 17h22
  4. [MySQL] Récupération d'indice d'une table
    Par pat06 dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 30/01/2008, 15h35
  5. Récupération d'Indice de fin de table
    Par Arsene12 dans le forum WinDev
    Réponses: 4
    Dernier message: 20/08/2007, 20h29

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