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 :

Calculs incrémentiels data.frame


Sujet :

R

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2018
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2018
    Messages : 6
    Par défaut Calculs incrémentiels data.frame
    Bonjour à tous,

    J'ai besoin des compétences de ce forum !
    Je vous explique mon soucis :

    J'ai un data.frame qui ressemble à ça :

    ID_sujet variable numero_visite
    1 125 1
    1 130 2
    1 115 3
    1 110 4
    2 125 1
    2 135 2
    2 123 3
    2 140 4
    2 126 5


    Etc.

    Ce que j'ai besoin de faire :

    - j'ai besoin de calculer l'écart-type de la variable (jusque là ça va)
    - par sujet (là aussi ça va, aucun soucis avec ddply du package plyr)
    - là ou ça se complique c'est que j'ai besoin de calculer cet écart -type au fur et à mesure des visites : par exemple pour le sujet 1, j'ai besoin de l'écart type pour la visite 2 calculé à partir des valeurs de la variable sur les visites 1 et 2, puis l'écart type à la visite 3, calculé à partir des visites 1, 2 et 3 et ainsi de suite !
    - enfin, le must ça serait que ces valeurs calculées puissent apparaître comme une nouvelle variable dans le même data.frame (avec 0 à la visite 1, la valeur à la visite 2 etc).

    J'ai essayé de trouver des solutions sur le net (d'habitude la documentation est riche pour R) mais là je sais même pas quels mots clefs utiliser pour ma recherche !

    En vous remerciant d'avance pour vos réponses qui me feraient gagner un temps considérable !

  2. #2
    Membre chevronné
    Inscrit en
    Février 2011
    Messages
    276
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 276
    Par défaut
    Bonjour,

    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
    27
    library(dplyr)
    fun <- function (x) 
    {
        res <- numeric(length(x))
        u <- 1
        for (i in seq_along(x)) {
            res[u] <- sd(x[seq_len(i)])
            u <- u + 1
        }
        res[1] <- 0
        res
    }
    tab %>% arrange(ID_sujet, numero_visite) %>% group_by(ID_sujet) %>% mutate(Sd = fun(variable))
    Source: local data frame [9 x 4]
    Groups: ID_sujet [2]
     
      ID_sujet variable numero_visite       Sd
         <int>    <int>         <int>    <dbl>
    1        1      125             1 0.000000
    2        1      130             2 3.535534
    3        1      115             3 7.637626
    4        1      110             4 9.128709
    5        2      125             1 0.000000
    6        2      135             2 7.071068
    7        2      123             3 6.429101
    8        2      140             4 8.098354
    9        2      126             5 7.328028
    cdlt

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2018
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2018
    Messages : 6
    Par défaut
    Bonjour,

    Cela fonctionne parfaitement !

    Cela m'évite de multiplier les daply manuellement (ce que j'avais commencé à faire faute de mieux).
    On m'avait également conseillé de passer par une matrice diagonale, mais là c'est encore plus efficace !!

    Merci beaucoup pour votre réponse rapide et efficace !

    Cordialement

  4. #4
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2018
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2018
    Messages : 6
    Par défaut
    Citation Envoyé par tototode Voir le message
    Bonjour,

    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
    27
    library(dplyr)
    fun <- function (x) 
    {
        res <- numeric(length(x))
        u <- 1
        for (i in seq_along(x)) {
            res[u] <- sd(x[seq_len(i)])
            u <- u + 1
        }
        res[1] <- 0
        res
    }
    tab %>% arrange(ID_sujet, numero_visite) %>% group_by(ID_sujet) %>% mutate(Sd = fun(variable))
    Source: local data frame [9 x 4]
    Groups: ID_sujet [2]
     
      ID_sujet variable numero_visite       Sd
         <int>    <int>         <int>    <dbl>
    1        1      125             1 0.000000
    2        1      130             2 3.535534
    3        1      115             3 7.637626
    4        1      110             4 9.128709
    5        2      125             1 0.000000
    6        2      135             2 7.071068
    7        2      123             3 6.429101
    8        2      140             4 8.098354
    9        2      126             5 7.328028
    cdlt
    Bonjour à nouveau,

    Je voulais vous demander si vous pouviez m'expliquer plus précisément votre code, car même s'il fonctionne très bien, je préfère toujours comprendre ce que je met dans mon code R ! De plus cela me permettra de comprendre la logique des boucles et donc de pouvoir en refaire moi-même !

    J'ai essayé de lire un peu sur les boucles R donc j'ai compris une partie du code :

    fun <- function sert à nommer la fonction que l'on crée
    res : sert à définir le nombre max d'itérations (ici la longueur du vecteur x)

    et c'est après que je suis perdu !

    En vous remerciant d'avance pour votre réponse.

    Cordialement

  5. #5
    Membre chevronné
    Inscrit en
    Février 2011
    Messages
    276
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 276
    Par défaut
    Bonjour,

    succinctement, fun est effectivement le nom de la fonction qui va faire les calculs d'écart type. Elle travaille sur un vecteur de valeurs, essaie par exemple fun(c(1,4,8)).
    res <- numeric(length(x)) ne sert pas à initier la boucle. Ca sert à créer un objet qui stockera les résultats, cet objet est un vecteur de valeurs numériques et de longueur identique à la série de donnée à traiter.
    u <- 1 c'est un compteur que j'incrémente à chaque itération (u <- u+1 dans la boucle) et qui dit à quelle position du vecteur res on doit stocker le résultat.
    for (i in seq_along(x)) { # ça c'est l'initialisation de la boucle. A chaque itération la valeur de l'objet "i" change. seq_along(x) ça crée un vecteur d'entier allant de 1 à la longueur de x avec un pas de 1, c'est équivalent à 1:length(x). Donc sur l'exemple fun(c(1,4,8)), seq_along(x) ça va créer un vecteur de valeurs : 1, 2, 3. Donc i aura d'abord pour valeur 1 puis 2 puis 3.
    res[u] <- sd(x[seq_len(i)]), seq_len(i) crée un vecteur de valeur allant de 1 à i, donc de 1 à 1, puis de 1 à 2, puis de 1à3, donc x[seq_len(i)] ça permet de ne récupérer d'abord que la première valeur de x, puis les deux premières valeurs de x, etc. sd c'est al fonction pour le calcul de l'écart-type (division en n-1).

    res[1] <- 0 parce que le calcul du premier ecart type renvoie NA, donc on le transforme en 0.

    Je m'apperçois que toute la partie avec u n'est pas nécessaire, fun pourrait s'écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    fun <- function (x) 
    {
        res <- numeric(length(x))
        for (i in seq_along(x)) {
            res[i] <- sd(x[seq_len(i)])
        }
        res[1] <- 0
        res
    }
    Comme il faut faire ça pour chaque ID_sujet, les fonctions du package dplyr sont très pratiques.
    tab %>% arrange(ID_sujet, numero_visite) veut dire qu'on trie les valeurs de tab par numéro de sujet puis numéro de visite pour être sur de faire les calculs de sd dans l'ordre.
    %>% group_by(ID_sujet) veut dire que les opérations seront faites pour chaque niveau de ID_sujet,
    mutate : que l'on va modifier ou créer une nouvelle colonne
    Sd = fun(variable) qu'elle s'apellera Sd et qu'elle sera issue de l'action de la fonction fun sur la colonne variable.

    Cordialement

  6. #6
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2018
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2018
    Messages : 6
    Par défaut
    Re bonjour,

    Super, merci beaucoup pour cette explication, j'y vois un peu plus clair !

    J'essaie de me faire un petit exercice d'application. Soit le tableau suivant :

    ID_SUJET Num_vis Date_vis
    1 1 date1
    1 2 date2
    1 3 date3
    2 1 date1
    2 2 date2
    2 3 date3
    2 4 date4


    Si je voulais créer une nouvelle variable pour connaitre le délai des visites par rapport à la première visite :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    fun <- function (x)
    { res <- numeric(length(x))
    u <- 1
    for (i in seq_along(x)) {
    res[u] <- as.numeric(difftime(x[seq_len(i+1)], x[seq_len(i)], units = "days")/365.25)}
    res
    }
    Je ne suis pas sûr du tout de moi ! J'ai commencé à lire sur les boucles hier

    Cordialement

  7. #7
    Membre chevronné
    Inscrit en
    Février 2011
    Messages
    276
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 276
    Par défaut
    Re,

    Pour savoir ce qu'il se passe dans un code, le plus simple est encore de prendre un exemple et de voir au cours de la fonction ce qu'il se passe, par exemple en mettant des print ou en utilisant debug :
    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
    27
    28
    29
    30
    31
    32
    33
    34
    fun <- function (x)
    { res <- numeric(length(x))
    u <- 1
    print("seq_along(x)")
    print(seq_along(x))
    for (i in seq_along(x)) {
      print("u")
      print(u)
      print("seq_len(i+1)")
      print(seq_len(i+1))
      print("seq_len(i)")
      print(seq_len(i))
      # etc...
      res[u] <- as.numeric(difftime(x[seq_len(i+1)], x[seq_len(i)], units = "days")/365.25)
      }
    res
    }
    test <- c(Sys.time(), Sys.time())
    fun(test)
    [1] "seq_along(x)"
    [1] 1 2
    [1] "u"
    [1] 1
    [1] "seq_len(i+1)"
    [1] 1 2
    [1] "seq_len(i)"
    [1] 1
    [1] "u"
    [1] 1
    [1] "seq_len(i+1)"
    [1] 1 2 3
    [1] "seq_len(i)"
    [1] 1 2
    [1] 0 0
    cdlt

Discussions similaires

  1. Extraire une sous data.frame
    Par manoir dans le forum R
    Réponses: 4
    Dernier message: 10/07/2009, 14h39
  2. Dupliquer les lignes d'une data. frame
    Par manoir dans le forum R
    Réponses: 2
    Dernier message: 09/07/2009, 18h25
  3. Mean par colonne dans une data frame
    Par manoir dans le forum R
    Réponses: 3
    Dernier message: 19/06/2009, 11h06
  4. Trier une data frame
    Par manoir dans le forum R
    Réponses: 4
    Dernier message: 28/04/2009, 16h29
  5. Réponses: 2
    Dernier message: 14/11/2008, 14h53

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