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 :

Extraction de valeurs selon condition


Sujet :

R

  1. #1
    Membre du Club
    Homme Profil pro
    Analyse système
    Inscrit en
    Juin 2018
    Messages
    180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Aveyron (Midi Pyrénées)

    Informations professionnelles :
    Activité : Analyse système
    Secteur : Alimentation

    Informations forums :
    Inscription : Juin 2018
    Messages : 180
    Points : 54
    Points
    54
    Par défaut Extraction de valeurs selon condition
    Bonjour,

    Je dispose d'un dataframe qui représente des caractéristiques de personnes, telles que la profession, le sexe, et l'utilisation du télétravail :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    data = data.frame(profession = sample(c("artisan", "employe", "cadre supérieur"), 10000, replace = TRUE), sexe = sample(c("M", "F"), 10000, replace = TRUE), en_teletravail = sample(c("Oui", "Non"), 10000, replace = TRUE))
    Je souhaiterais créer un nouveau dataframe, issus d'une extraction des valeurs de "data", de telle sorte :
    - Qu'il y ait 20% d'hommes et 80% de femmes
    - Et, qu'il y ait 60% d'artisans, 20% d'employes, et 20% de cadres supérieur
    - Et, qu'il y ait 50% de "Oui" à l'utilisation du télétravail.

    Est-il possible de faire ceci sur R ?
    Merci

  2. #2
    Membre expérimenté
    Inscrit en
    Novembre 2009
    Messages
    703
    Détails du profil
    Informations forums :
    Inscription : Novembre 2009
    Messages : 703
    Points : 1 311
    Points
    1 311
    Par défaut échantillonage dataframe stratifié
    Bonjour,

    La fonction stratified() du package splitstackshape permet de créer un échantillonnage à partir d'un dataframe :

    • Dataframe initial

    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
    set.seed(1) 
    data1 <- data.frame(profession = sample(c("artisan", "employé", "cadre supérieur"), 10000, replace = TRUE), 
                        sexe = sample(c("M", "F"), 10000, replace = TRUE), 
                        en_teletravail = sample(c("Oui", "Non"), 10000, replace = TRUE),
                        stringsAsFactors = TRUE)
     
    prop.table(table(data1$profession))
    #> 
    #>         artisan cadre supérieur         employé 
    #>          0.3424          0.3284          0.3292
    prop.table(table(data1$sexe))
    #> 
    #>      F      M 
    #> 0.4894 0.5106
    prop.table(table(data1$en_teletravail))
    #> 
    #>   Non   Oui 
    #> 0.503 0.497
    • Construction d'un dataframe avec les bonnes proportions

    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
    data2 <- data.frame(profession = sample(c("artisan", "employé", "cadre supérieur"), 1000000, replace = TRUE, prob = c(0.6, 0.2, 0.2)), 
                        sexe = sample(c("M", "F"), 1000000, replace = TRUE, prob = c(0.2,0.8)), 
                        en_teletravail = sample(c("Oui", "Non"), 1000000, replace = TRUE, prob = c(0.5, 0.5)),
                        stringsAsFactors = TRUE)
     
    prop.table(table(data2$profession))
    #> 
    #>         artisan cadre supérieur         employé 
    #>        0.599907        0.200212        0.199881
    prop.table(table(data2$sexe))
    #> 
    #>        F        M 
    #> 0.800348 0.199652
    prop.table(table(data2$en_teletravail))
    #> 
    #>      Non      Oui 
    #> 0.500483 0.499517
    • Construction d'une variable groupe correspondant aux différentes combinaisons

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    data2$groupe <- paste(data2$profession, data2$sexe, data2$en_teletravail)
    • Calcul des effectifs de chaque combinaison dans le dataframe stratifié

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    gsize <- 200 * round(prop.table(table(data2$groupe)), 2)
    gsize
    #> 
    #>         artisan F Non         artisan F Oui         artisan M Non 
    #>                    48                    48                    12 
    #>         artisan M Oui cadre supérieur F Non cadre supérieur F Oui 
    #>                    12                    16                    16 
    #> cadre supérieur M Non cadre supérieur M Oui         employé F Non 
    #>                     4                     4                    16 
    #>         employé F Oui         employé M Non         employé M Oui 
    #>                    16                     4                     4
    gsize <- as.list(gsize)
    • Création du dataframe stratifié

    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
    data3 <- splitstackshape::stratified(data1, c("profession", "sexe", "en_teletravail"), gsize)
     
    prop.table(table(data3$profession))
    #> 
    #>         artisan cadre supérieur         employé 
    #>             0.6             0.2             0.2
    prop.table(table(data3$sexe))
    #> 
    #>   F   M 
    #> 0.8 0.2
    prop.table(table(data3$en_teletravail))
    #> 
    #> Non Oui 
    #> 0.5 0.5
     
    # Created on 2020-09-17 by the reprex package (v0.3.0.9001)
    Cordialement,

  3. #3
    Membre du Club
    Homme Profil pro
    Analyse système
    Inscrit en
    Juin 2018
    Messages
    180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Aveyron (Midi Pyrénées)

    Informations professionnelles :
    Activité : Analyse système
    Secteur : Alimentation

    Informations forums :
    Inscription : Juin 2018
    Messages : 180
    Points : 54
    Points
    54
    Par défaut
    Un grand merci pour votre réponse, qui répond complètement à mon besoin. En plus, c'est une librairie que je ne connaissais pas !

    J'ai cependant une petite question. J'ai tenté d'appliquer cette méthodologie sur le dataframe sur lequel je travaille actuellement. Je reçois l'erreur "Error in splitstackshape::stratified(data1, c("categorie_metier"), gsize) : Incompatible sizes supplied".

    Voici comment je procède :

    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
     
    #Génération d'un dataframe, semblable à celui sur lequel je travaille
    data1 <- data.frame(categorie_metier = sample(c("agriculteur", "artisan", "autre", "cadres", "employes", "ouvriers", "prof_int"), 429, replace = TRUE, prob = c(0.01, 0.05, 0.14, 0.41, 0.25, 0.04, 0.10)), stringsAsFactors = TRUE)
     
    #Génération du second dataframe, avec les probabilités des modalités choisies
    data2 <- data.frame(categorie_metier = sample(c("agriculteur", "artisan", "autre", "cadres", "employes", "ouvriers", "prof_int"), 100000, replace = TRUE, prob = c(0.01, 0.03, 0.27, 0.21, 0.13, 0.10, 0.25)), stringsAsFactors = TRUE)
     
    #Collage du champ
    data2$groupe <- paste(data2$categorie_metier)
     
    #Construction de gsize, de telle manière à ce que je récupère un dataframe de 50 entrées
    gsize <- 50 * round(prop.table(table(data2$groupe)), 1)
    gsize <- as.list(gsize)
     
    #Génération du dataframe
    data3 <- splitstackshape::stratified(data, c("categorie_metier"), gsize)
    Error in splitstackshape::stratified(data1, c("categorie_metier"), gsize) : 
      Incompatible sizes supplied
    Pourtant, gsize ne comporte pas de modalités supérieures à data1...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    > table(data1$categorie_metier)
    agriculteur     artisan       autre      cadres    employes    ouvriers    prof_int 
              6          14          60         177         121           8          43 
     
    > gsize
    agriculteur     artisan       autre      cadres    employes    ouvriers    prof_int 
              0           0          15          10           5           5          10
    A quoi cela est-il du ?
    Merci.

  4. #4
    Membre expérimenté
    Inscrit en
    Novembre 2009
    Messages
    703
    Détails du profil
    Informations forums :
    Inscription : Novembre 2009
    Messages : 703
    Points : 1 311
    Points
    1 311
    Par défaut échantillonage dataframe stratifié
    Bonjour,

    Je pense que c'est parce que vous avez des groupes vides :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    gsize <- 50 * round(prop.table(table(data2$categorie_metier)), 1)
    gsize
    #> 
    #> agriculteur     artisan       autre      cadres    employes    ouvriers 
    #>           0           0          15          10           5           5 
    #>    prof_int 
    #>          10
    sum(gsize)
    #> [1] 45
    gsize <- as.list(gsize)
     
    #Génération du dataframe
    data3 <- splitstackshape::stratified(data1, "categorie_metier", gsize)
    #> Error in splitstackshape::stratified(data1, "categorie_metier", gsize): Incompatible sizes supplied
    Ça fonctionne en enlevant les groupes vides :

    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
    gsize <- 50 * round(prop.table(table(data2$categorie_metier)), 1)
    gsize
    #> 
    #> agriculteur     artisan       autre      cadres    employes    ouvriers 
    #>           0           0          15          10           5           5 
    #>    prof_int 
    #>          10
    sum(gsize)
    #> [1] 45
    gsize <- gsize[gsize != 0]
    gsize
    #> 
    #>    autre   cadres employes ouvriers prof_int 
    #>       15       10        5        5       10
    gsize <- as.list(gsize)
    data3 <- splitstackshape::stratified(data1, "categorie_metier", gsize,
                                         select = list(categorie_metier = names(gsize)))
    data3$categorie_metier <- factor(data3$categorie_metier)
    round(prop.table(table(data3$categorie_metier)), 2)
    #> 
    #>    autre   cadres employes ouvriers prof_int 
    #>     0.33     0.22     0.11     0.11     0.22
    ou en augmentant la taille des groupes :

    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
    gsize <- 100 * round(prop.table(table(data2$categorie_metier)), 2)
    gsize
    #> 
    #> agriculteur     artisan       autre      cadres    employes    ouvriers 
    #>           1           3          27          21          13          10 
    #>    prof_int 
    #>          25
    sum(gsize)
    #> [1] 100
    gsize <- as.list(gsize)
     
    #Génération du dataframe
    data3 <- splitstackshape::stratified(data1, "categorie_metier", gsize)
    prop.table(table(data3$categorie_metier))
    #> 
    #> agriculteur     artisan       autre      cadres    employes    ouvriers 
    #>        0.01        0.03        0.27        0.21        0.13        0.10 
    #>    prof_int 
    #>        0.25
     
    # Created on 2020-09-19 by the reprex package (v0.3.0.9001)
    Notez aussi qu'il n'est pas nécessaire de créer une variable groupe si vous utilisez une seule variable de stratification.

    Cordialement,

  5. #5
    Membre du Club
    Homme Profil pro
    Analyse système
    Inscrit en
    Juin 2018
    Messages
    180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Aveyron (Midi Pyrénées)

    Informations professionnelles :
    Activité : Analyse système
    Secteur : Alimentation

    Informations forums :
    Inscription : Juin 2018
    Messages : 180
    Points : 54
    Points
    54
    Par défaut
    Merci beaucoup pour vos conseils

  6. #6
    Membre du Club
    Homme Profil pro
    Analyse système
    Inscrit en
    Juin 2018
    Messages
    180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Aveyron (Midi Pyrénées)

    Informations professionnelles :
    Activité : Analyse système
    Secteur : Alimentation

    Informations forums :
    Inscription : Juin 2018
    Messages : 180
    Points : 54
    Points
    54
    Par défaut
    Après avoir vu la dernière modification que vous avez faite, je me permet de revenir une dernière fois pour tenter d'adapter le programme, dans le cas où on a plusieurs groupes à tester (categorie_metier et en_teletravail) :

    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
     
    library(splitstackshape)
     
    #Génération du dataframe, semblable à celui sur lequel je travaille
    data1 <- data.frame(categorie_metier = sample(c("agriculteur", "artisan", "autre", "cadres", "employes", "ouvriers", "prof_int"), 429, replace = TRUE, prob = c(0.01, 0.05, 0.14, 0.41, 0.25, 0.04, 0.10)), en_teletravail = sample(c("0", "1"), 429, replace = TRUE, prob = c(0.59, 0.41)), stringsAsFactors = TRUE)
     
    #Dans le data1, je crée une colonne qui colle les paramètres
    data1$groupe = paste(data1$categorie_metier, data1$en_teletravail, sep = "")
     
    #Génération du dataframe avec les probabilités souhaitées
    data2 <- data.frame(categorie_metier = sample(c("agriculteur", "artisan", "autre", "cadres", "employes", "ouvriers", "prof_int"), 1000000, replace = TRUE, prob = c(0.01, 0.03, 0.27, 0.21, 0.13, 0.10, 0.25)), en_teletravail = sample(c("0", "1"), 1000000, replace = TRUE, prob = c(0.991, 0.009)), stringsAsFactors = TRUE)
    data2$groupe <- paste(data2$categorie_metier, data2$en_teletravail, sep = "")
     
    #On souhaite obtenir un dataframe avec 50 entrées
    gsize <- 50 * round(prop.table(table(data2$groupe)), 1)
    gsize = gsize[gsize != 0]
    gsize = as.list(gsize)
     
    #Génération du dataframe en sortie
    data3 <- splitstackshape::stratified(data1, c("categorie_metier", "en_teletravail"), gsize, select = list(groupe = names(gsize)))
    Error in sample.int(length(x), size, replace, prob) : 
      premier argument incorrect
    Aurais-je oublié quelque chose ?

  7. #7
    Membre expérimenté
    Inscrit en
    Novembre 2009
    Messages
    703
    Détails du profil
    Informations forums :
    Inscription : Novembre 2009
    Messages : 703
    Points : 1 311
    Points
    1 311
    Par défaut échantillonnage dataframe stratifié
    Bonjour,

    L'instruction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    data3 <- splitstackshape::stratified(data1, c("categorie_metier", "en_teletravail"), gsize, select = list(groupe = names(gsize)))
    suppose que les deux variables soient séparées par une espace, cf. l'exemple donné dans l'aide :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    set.seed(1)
    DF <- data.frame(
      ID = 1:100,
      A = sample(c("AA", "BB", "CC", "DD", "EE"), 100, replace = TRUE),
      B = rnorm(100), C = abs(round(rnorm(100), digits=1)),
      D = sample(c("CA", "NY", "TX"), 100, replace = TRUE),
      E = sample(c("M", "F"), 100, replace = TRUE))
     
    # Works with multiple groups as well
    stratified(DF, c("D", "E"), 
               c("NY F" = 2, "NY M" = 3, "TX F" = 1, "TX M" = 1,
                 "CA F" = 5, "CA M" = 1))
    Votre programme fonctionne si vous remplacez c("categorie_metier", "en_teletravail") par "groupe" :

    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
    # Génération du dataframe, semblable à celui sur lequel je travaille
    data1 <- data.frame(categorie_metier = sample(c("agriculteur", "artisan", "autre", "cadres", "employes", "ouvriers", "prof_int"), 
                        429, replace = TRUE, prob = c(0.01, 0.05, 0.14, 0.41, 0.25, 0.04, 0.10)), 
                        en_teletravail = sample(c("0", "1"), 429, replace = TRUE, prob = c(0.59, 0.41)), stringsAsFactors = TRUE)
     
    # Dans le data1, je crée une colonne qui colle les paramètres
    data1$groupe = paste0(data1$categorie_metier, data1$en_teletravail)
     
    # Génération du dataframe avec les probabilités souhaitées
    data2 <- data.frame(categorie_metier = sample(c("agriculteur", "artisan", "autre", "cadres", "employes", "ouvriers", "prof_int"), 
                        1000000, replace = TRUE, prob = c(0.01, 0.03, 0.27, 0.21, 0.13, 0.10, 0.25)), 
                        en_teletravail = sample(c("0", "1"), 1000000, replace = TRUE, prob = c(0.991, 0.009)), stringsAsFactors = TRUE)
    data2$groupe <- paste0(data2$categorie_metier, data2$en_teletravail)
     
    # On souhaite obtenir un dataframe avec 50 entrées
    gsize <- 50 * round(prop.table(table(data2$groupe)), 1)
    gsize = gsize[gsize != 0]
    sum(gsize)
    #> [1] 45
    gsize = as.list(gsize)
     
    # Génération du dataframe en sortie
    data3 <- splitstackshape::stratified(data1, c("groupe"), gsize, select = list(groupe = names(gsize)))
    round(prop.table(table(data3$categorie_metier)), 2)
    #> 
    #> agriculteur     artisan       autre      cadres    employes    ouvriers 
    #>        0.00        0.00        0.33        0.22        0.11        0.11 
    #>    prof_int 
    #>        0.22
    round(prop.table(table(data3$en_teletravail)), 2)
    #> 
    #> 0 1 
    #> 1 0
    N.B. 1 : Vous créez data2 avec 9 télétravail pour 1000, ce qui correspond à 0 pour 50.
    N.B. 2 : L'effectif de l'échantillon créé est de 45.

    Cordialement,

  8. #8
    Membre du Club
    Homme Profil pro
    Analyse système
    Inscrit en
    Juin 2018
    Messages
    180
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Aveyron (Midi Pyrénées)

    Informations professionnelles :
    Activité : Analyse système
    Secteur : Alimentation

    Informations forums :
    Inscription : Juin 2018
    Messages : 180
    Points : 54
    Points
    54
    Par défaut
    Un énorme merci pour ces explications. Je met la discussion en "Résolu".

    Cordialement.

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

Discussions similaires

  1. Extraction de données selon conditions entre 2 fichiers
    Par kemherar dans le forum Macros et VBA Excel
    Réponses: 12
    Dernier message: 08/05/2015, 15h00
  2. [XL-2003] Différence de valeurs selon conditions sur 2 colonnes
    Par arkhang dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 07/08/2014, 14h20
  3. [XL-2007] Copier des valeurs selon conditions
    Par interloll dans le forum Excel
    Réponses: 3
    Dernier message: 22/02/2013, 19h08
  4. [CR 9] appel valeur selon condition formule
    Par perezlyon dans le forum SAP Crystal Reports
    Réponses: 4
    Dernier message: 16/02/2011, 14h19
  5. Réponses: 2
    Dernier message: 01/05/2009, 09h59

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