Equivallent de macros SAS pour automatiser la création de sous-tables

Postez ici vos questions, réponses, commentaires ou suggestions - Les sujets seront ultérieurement répartis dans les archives par les modérateurs

Modérateur : Groupe des modérateurs

Stéphane Adrover
Messages : 8
Enregistré le : 13 Nov 2017, 10:56

Equivallent de macros SAS pour automatiser la création de sous-tables

Messagepar Stéphane Adrover » 14 Nov 2017, 09:49

Bonjour et merci me m’accueillir sur votre forum.

Je suis un pratiquant de longue date de SAS, mais n’ayant plus la licence sur mon nouveau poste, je suis contraint de passer à R, et de me débrouiller à peu près tout seul. Le choc culturel est assez violent, disons-le.
Un des principaux problèmes que je rencontre est de trouver une alternative aux macros SAS.

Un exemple : ci-joint un modèle de fichier que je dois traiter avec des enregistrements pour environ 200 établissements sur une série chronologique (pour une enquête agricole). Il se trouve que pour les données les plus récentes, seul une partie des établissements ont répondu au questionnaire. Je veux donc faire une régression entre les données (prix1,prix2…) de chaque établissement non répondant avec la moyenne pour les répondants afin d’imputer des valeurs pour les mois non remplis, si l’ajustement est de bonne qualité.
Le fichier a cette allure :
Ident_etab anmois prix1 prix2
1 201501 250 360
1 201502 301 438
1 201503 319 337
1 201504 285 313
1 201505 252 338
1 201506 300 393
1 201507 401 464
1 201508 415 495
1 201509 321 390
1 201510 201 344
1 201511 185 246
1 201512 155 274
1 etc etc etc
2 201501 275 422
2 201502 321 356
2 201503 322 418
2 etc etc etc


Pour récupérer dans des tables différentes les valeurs individuelles afin de faire les tests, en SAS j’aurais fait quelque chose de ce genre:

Code : Tout sélectionner

%macro etab ;
%do i=1 %to 200;
data dat&I;
set fichier;
if ident_etab = &I;
%end;
%mend;
%etab;


Or j’ai beau chercher un moyen d’automatiser cela dans R, par des boucles ou autre, je n’y arrive pas. Auriez-vous une solution ? Nb, désolé si la réponse figure déjà quelque part, mais je n’ai pas trouvé.

Stéphane

Eric Casellas
Messages : 767
Enregistré le : 06 Jan 2009, 14:59

Re: Equivallent de macros SAS pour automatiser la création de sous-tables

Messagepar Eric Casellas » 14 Nov 2017, 10:06

Bonjour,

Voici 2 exemples de code pour extraire dans des data.frame séparés selon une colonne utilisée comme identifiant :

Code : Tout sélectionner

X <- data.frame(Ident_etab=sample(1:10, 100, replace=TRUE), anmois=rnorm(100), prix1=rnorm(100), prix2=rnorm(100))

XX1 <- lapply(unique(X$Ident_etab), function(x){X[X$Ident_etab==x, ]})

XX2 <- list()
for (i in unique(X$Ident_etab)) {
  XX2[[i]] <- X[X$Ident_etab==i, ]
}
Eric

Dominique Soudant
Messages : 758
Enregistré le : 23 Avr 2008, 11:12
Contact :

Re: Equivallent de macros SAS pour automatiser la création de sous-tables

Messagepar Dominique Soudant » 14 Nov 2017, 10:11

Bonjour,

En 2007 j’avais écrit des milliers de ligne de SAS et pas une de R : ça va aller.

2 réponses à ta question
1) il faut que tu regardes, que tu maîtrises les fonction by apply sapply tapply lapply, toute cette famille de fonctions qui permettent de traiter un vecteur une matrice un dataframe, le cas échéant, avec un index de groupe. Dans ton cas une piste est

Code : Tout sélectionner

MonDF <- lire le fichier de données
by(MonDF
  ,MonDF$ident_etab
  ,MaFonctionQuiFaitMesTests
)

2) il faut que tu maîtrises la notion de fonction qui est la même que dans les tous les langages procéduraux, c’est plutôt SAS qui fait figure d’exception avec son code étrange.

@+

Stéphane Adrover
Messages : 8
Enregistré le : 13 Nov 2017, 10:56

Re: Equivallent de macros SAS pour automatiser la création de sous-tables

Messagepar Stéphane Adrover » 14 Nov 2017, 13:27

Ok merci pour ces réponses, je vais tenter d'en faire quelque chose.

Pierre-Yves Berrard
Messages : 1029
Enregistré le : 12 Jan 2016, 23:30

Re: Equivallent de macros SAS pour automatiser la création de sous-tables

Messagepar Pierre-Yves Berrard » 14 Nov 2017, 13:41

Bonjour,

Un gros +1 sur le message de Dominique, tant sur le point 1) que sur le point 2).

J'ajouterais la possibilité de construire un data.frame imbriqué avec :

Code : Tout sélectionner

dplyr::group_by(Ident)
puis

Code : Tout sélectionner

tidyr::nest()

Après, il faut savoir se servir de l'objet un peu déroutant (surtout pour un SASseur) qu'on a créé.
Je reste à ta disposition si tu veux explorer cette piste.
PY

Stéphane Adrover
Messages : 8
Enregistré le : 13 Nov 2017, 10:56

Re: Equivallent de macros SAS pour automatiser la création de sous-tables

Messagepar Stéphane Adrover » 15 Nov 2017, 12:18

Euh … je suis un peu perdu avec les réponses de Dominique et Pierre-Yves. Je suis trop novice pour comprendre ce que je pourrais en faire compte tenu du problème que je cherche à résoudre. Quant aux suggestions d’Eric, je les ai testées, ça me donne bien des listes que je peux visualiser, mais ce dont j’ai besoin, c’est de générer un data.frame en sortie pour chaque établissement , à la manière de ce que je peux faire avec une macro sas comme indiqué ci-dessus.

Eric Casellas
Messages : 767
Enregistré le : 06 Jan 2009, 14:59

Re: Equivallent de macros SAS pour automatiser la création de sous-tables

Messagepar Eric Casellas » 15 Nov 2017, 12:45

Stéphane Adrover a écrit :Quant aux suggestions d’Eric, je les ai testées, ça me donne bien des listes que je peux visualiser, mais ce dont j’ai besoin, c’est de générer un data.frame en sortie pour chaque établissement , à la manière de ce que je peux faire avec une macro sas comme indiqué ci-dessus.

Bonjour,

Chaque élément des listes XX1 et XX2 de mes exemples sont des data.frame.

Sinon si tu veux avoir un objet différents pour chaque tu peut faire quelque chose du genre :

Code : Tout sélectionner

X <- data.frame(Ident_etab=sample(1:10, 100, replace=TRUE), anmois=rnorm(100), prix1=rnorm(100), prix2=rnorm(100))
for (i in unique(X$Ident_etab)) {
  assign(paste0("df_", i),  X[X$Ident_etab==i, ])
}


Eric
Eric

Stéphane Adrover
Messages : 8
Enregistré le : 13 Nov 2017, 10:56

Re: Equivallent de macros SAS pour automatiser la création de sous-tables

Messagepar Stéphane Adrover » 15 Nov 2017, 13:41

Impeccable ça marche, merci beaucoup !

François Bonnot
Messages : 537
Enregistré le : 10 Nov 2004, 15:19
Contact :

Re: Equivallent de macros SAS pour automatiser la création de sous-tables

Messagepar François Bonnot » 16 Nov 2017, 07:35

ce dont j’ai besoin, c’est de générer un data.frame en sortie pour chaque établissement

Bonjour,
Je pense que c'est davantage une habitude héritée de SAS qu'un réel besoin (mais je ne connais pas la situation particulière qui le justifie peut-être).
Pour ma part je trouve beaucoup plus pratique de travailler sur les membres d''une seule liste de data.frames comme suggéré par Eric, en utilisant plutôt la fonction split():

Code : Tout sélectionner

X <- data.frame(Ident_etab=sample(1:10, 100, replace=TRUE), anmois=rnorm(100), prix1=rnorm(100), prix2=rnorm(100))
XX <- split(X,X["Ident_etab"])
XX

puis ensuite utiliser lapply pour faire des calculs sur chaque membre, par exemple (pour les corrélations entre prix1 et prix2):

Code : Tout sélectionner

li <- lapply(XX, function(z) cor(z$prix1,z$prix2))
li
do.call(rbind,li)

On peut obtenir le même résultat avec by (et avec bien d'autres fonctions d'autre packages), mais c'est assez pratique de commencer par constituer la liste XX pour l'utiliser ensuite avec des fonctions différentes.
François

Stéphane Adrover
Messages : 8
Enregistré le : 13 Nov 2017, 10:56

Re: Equivallent de macros SAS pour automatiser la création de sous-tables

Messagepar Stéphane Adrover » 16 Nov 2017, 09:15

Je pense que c'est davantage une habitude héritée de SAS qu'un réel besoin


Sans doute ! On ne se défait pas facilement de 30 ans de pratique exclusive de SAS :)

Serge Rapenne
Messages : 1426
Enregistré le : 20 Aoû 2007, 15:17
Contact :

Re: Equivallent de macros SAS pour automatiser la création de sous-tables

Messagepar Serge Rapenne » 16 Nov 2017, 10:38

Bonjour,

Je n'ai jamais utilisé SAS mais en tant qu'ancien utilisateur de Excel, je sais qu'au fur et à mesure de l'amélioration de mes connaissances dans R, j'en suis venu à privilégier de plus en plus des structures de données en lignes (appelé format long dans R) à des structures de données en colonnes (format large).

Code : Tout sélectionner

#Avant j'utilisais des structures du style

        Date           X          Y         Z
1 2009-01-01  0.94867232  0.8662939  1.393413
2 2009-01-02 -0.77868010 -1.9967277 -3.612206
3 2009-01-03  0.30871752 -0.3597960 -3.825249
4 2009-01-04  0.08277307 -1.4445555 -3.432795

#maintenant je préfère de loin utiliser

            Date identifiant      valeur
1  2009-01-01           X  0.94867232
2  2009-01-02           X -0.77868010
3  2009-01-03           X  0.30871752
4  2009-01-04           X  0.08277307
5  2009-01-01           Y  0.86629394
6  2009-01-02           Y -1.99672770
7  2009-01-03           Y -0.35979599
8  2009-01-04           Y -1.44455550
9  2009-01-01           Z  1.39341280
10 2009-01-02           Z -3.61220646
11 2009-01-03           Z -3.82524931
12 2009-01-04           Z -3.43279486

R contient un grand nombre de fonction qui amha permettent de traiter plus facilement les données au format long par ex by, tapply, aggregate dans les fonctions de base de R et ce format est encore plus pratique si on utilise des package comme dplyr, ggplot2 ...

mes 2 centimes

Serge


Retourner vers « Questions en cours »

Qui est en ligne

Utilisateurs parcourant ce forum : Google [Bot] et 1 invité