Analyse de données
J'ai une base de données avec beaucoup d'individus et 4 variables ( 46 modalités). les variables sont sous la forme d'un tableau disjonctif complet. Je veux effectuer une classification sur les variables. Ici, je ne m'interesse qu'aux variables et non aux individus. Je veux savoir quelles modalités peuvent être regroupées. Comment faire une classification? Il existe peut-être une autre méthode que les classifications ?
Bonjour. Pour trouver des similitudes entre modalités de variables, la technique usuelle est de faire une ACM avec une proc CORRESP, et de regarder l'espace des variables pour y repérer des proximités. Cependant, on peut effectivement imaginer "automatiser" cette recherche avec une classification hiérarchique ; pour les variables quantitatives, SAS propose d'ailleurs la proc VARCLUS qui fait ce genre d'agrégations. Pour réussir quelque chose de semblable sur des données quali, il faut enchaîner une proc CORRESP (pour obtenir les coordonnées factorielles des modalités), une proc CLUSTER (pour la CAH) et une proc TREE (pour afficher l'arbre d'agrégation). D'un point de vue code, ça ressemblerait à :
/* création du tableau disjonctif complet */ PROC TRANSREG DATA=scoring.assur DESIGN NOPRINT ; MODEL CLASS(marque prof c_permis zontarif / ZERO=NONE) ; OUTPUT OUT=work.tdc ; RUN ; /* recuperation des coordonnées factorielles */ ODS OUTPUT colCoors = work.variables ; PROC CORRESP DATA=work.tdc NOROW DIMENS=%EVAL(&_trgindn-4) ; VAR &_trgind ; RUN ; /* CAH */ PROC CLUSTER DATA=work.variables OUTTREE = work.dendo METHOD=WARD ; VAR dim: ; ID label ; RUN ; /* affichage du dendogramme */ PROC TREE DATA=work.dendo HORIZONTAL ; ID label ; RUN ;
Bonjour, Voilà mon souci : je voudrais faire une Classification sur une énorme base (env 2 millions de lignes). Ce sont des données qualitatives, alors je dois passer par une ACM, donc construire un Tableau Disjonctif Complet (en tout j'ai 3 variables et 11*97*18 modalités). Seulement SAS bloque un peu beaucoup (il a mouliné toute la nuit et n'a pas avancé...)! La proc transreg que vous proposez dans cette FAQ n'est-elle pas appropriée ici? Ma base est-elle trop volumineuse pour un tel traitement? Si oui, comment faire ma classification? Merci beaucoup pour votre éclairage!
Deux pistes à explorer pour que votre traitement puisse se faire dans un temps acceptable (et, vu vos volumes, se faire tout court !).
1) travailler uniquement sur un échantillon : au lieu des 2 millions de lignes, vous pourriez construire une typologie sur seulement 10% d'entre eux, et ensuite chercher les règles de construction des classes (par un modèle statistique, ou plus simplement par une caractérisation univariée) pour dispatcher l'ensemble de vos lignes dans les différentes classes. 2) réduire le nombre de modalités d'une de vos valeurs : 97 valeurs me paraît un nombre un peu excessif. D'autant que cela risque de déséquilibrer fortement l'ACM (les premiers axes se concentreront sur l'information contenue dans cette variable et pas dans les 2 autres) Vous pourriez faire un recodage pour vous ramener à une vingtaine de valeurs ; non seulement ça équilibre l'ACM, mais en plus la taille des fichiers à traiter (tableau disjonctif complet en entrée de la procédure Corresp, et le tableau de Burt qu'elle construit en interne) sera plus raisonnable. Comment faire votre recodage ? Déjà sur des critères métier, je pense. Et également en faisant une ACM sur cette variable uniquement, dans l'espace des variables seulement, de préférence sur un échantillon aléatoire de vos deux millions de lignes. Pour cette ACM préalable, la syntaxe SAS est la suivante :PROC CORRESP DATA = votreTableSAS MCA SHORT ; TABLES votreVariableA97Modalites ; RUN ;
Si vous avez une version 9 de SAS, vous pouvez ajouter les deux instructions suivantes avant la procédure correspondante :
ODS GRAPHICS ON ; ODS HTML FILE = "c:\temp\sorties ACM.htm" GPATH = "c:\temp" (URL=NONE) ; Et ODS HTML CLOSE ;
après l'instruction RUN ; à la fin du programme.
Non seulement vos sorties seront plus jolies dans une page Web (changer éventuellement c:\temp pour un autre répertoire dans les deux options qui y font référence) mais en plus ODS GRAPHICS ajoutera directement le premier plan factoriel dans l'espace des variables : il ne vous reste "qu'à" fusionner les modalités qui sont proches dans ce plan.PROC PLOT DATA = tableSAS ; PLOT varY * varX = "#" $ variableTexte ; RUN ; QUIT ;Le signe # sert de marqueur aux points (il peut être remplacé par ce que l'on veut) et variableTexte contient les noms de modalités, identifiants d'individus, etc. A noter qu'à partir de la version 9.1 de SAS, ODS GRAPHICS produit le 1er plan factoriel d'une AFC avec la procédure CORRESP. En revanche, il nécessitera SAS/GRAPH en version 9.2 (et redevient dans SAS/Base à partir de SA 9.3 !!!).
Bonjour.
Je veux faire une classification sur les individus d'un tableau disjonctif complet. Pouvez-vous me donner le code sous SAS ? D'avance merci.
Bonjour.Comme votre point de départ est un tableau disjonctif complet, il est préférable de faire une ACM (PROC CORRESP) au préalable. On récupère les coordonnées factorielles des observations dans la table créée par l'option OUTC de la PROC CORRESP (filtrer uniquement les lignes où _TYPE_="OBS"). La procédure CLUSTER construit ensuite une CAH sur les coordonnées factorielles :
PROC CLUSTER DATA = tableSAS OUTTREE = tableDendogramme ; VAR dim: ; RUN ;La table créée par l'option OUTTREE contient les informations nécessaires au dessin du graphique de fusion des classes (dendogramme ou graphique arborescent). On obtient ce dernier par la procédure TREE :
PROC TREE DATA = tableDendogramme ; RUN ;Une fois choisi le bon nombre de classes, vous exécutez une dernière fois la procédure TREE pour obtenir l'affectation des individus aux classes :
PROC TREE DATA = tableDendogramme OUT = tableClassement NCLUSTERS = nbClasses ; RUN ;
Bonjour. Que vous ayez deux, trois ou deux cents variables à inclure dans l'ACM n'est pas source de différences dans le programme SAS. Si vous partez d'une table SAS qui est déjà un tableau disjonctif complet, c'est assez simple. Si ce n'est pas le cas, vous pouvez construire un TDC avec la procédure TRANSREG. La procédure CORRESP utilise la syntaxe suivante :
PROC CORRESP DATA = tableau_disjonctif_complet
NOROW=PRINT OUTC = tableSAS_sortie ;
VAR listeVariablesIndicatricesDuTDC ;
RUN ;
Deux remarques :
1) NOROW=PRINT est une option conseillée si vous travaillez sur un nombre important d'observations, elle évite l'édition dans la fenêtre OUTPUT des coordonnées factorielles, cosinus et autres qualités de chaque observation ;
2) si vous avez construit le TDC avec la procédure TRANSREG, la liste des variables indicatrices à spécifier dans VAR est : VAR &_trgind ;
Bonjour, Comment savoir si on doit réaliser un AFC ou une ACP sur un jeu données. Est-ce que SAS est capable de faire le choix tout seul ou y a-t-il un moyen d' effectuer une ACP ou une AFC avec SAS? Merci
Pour choisir, un moyen simple : les ACP se font sur des données exclusivement continues (quantitatives) et les AFC et ACM sur des données discrètes (qualitatives). Si vous avez des variables des deux types, le plus simple est de mettre en tranches les variables quantitatives et de faire une AFC du tout.
SAS ne fait pas le choix pour vous mais propose deux procédures : PRINCOMP pour les ACP, et CORRESP pour les AFC et ACM. Les sorties de ces deux procédures sont assez limitées en intérêt, aussi est-il souvent nécessaire d'enchaîner une série de procédures graphiques pour obtenir des beaux résultats (axes factoriels, projection des individus et des variables dans les plans factoriels, ...).
N'hésitez donc pas à vous intéresser aux tables produites par ces deux procédures (options OUT= et OUTSTAT=) qui vous permettront ensuite d'enchaîner les traitements pour avoir des résultats exploitables.
Arbre de décision
Quand je spécifie une probabilité a priori (Prior proba) dans un noeud Tree, il prend cette proba pour l'échantillon d'apprentissage, de validation et de test. Or moi, ce que je voudrais, c'est qu'il prenne cette proba pour apprendre et qu'il valide et teste sur un échantillon normal. A part dupliquer les individus à qui je veux donner une plus grande importance, comment résoudre ce problème ?
Pas de possibilité (connue de nous au moins) de n'appliquer les probas a priori qu'à l'échantillon d'apprentissage. En fait, ces probas sont considérées comme des coûts (matrice de coût et profit) qui s'appliquent tout le temps. Par contre, l'aide (EM Reference dans le menu Help de SEM) est assez détaillée sur le rôle de ces probas, en plus y a de fort belles images.
Bonjour,
J'aimerais effectuer un arbre de régression, à savoir un arbre avec une cible quantitative. Cela est-il possible avec Sas EM? Et si oui, comment? Les arbres de décisions sont-ils possibles avec Sas Guide ou Sas Base? Merci pour votre aide.
Oui, il est possible d'utiliser SAS EM pour construire des arbres de régression. Pour cela, il suffit de déclarer comme variable cible une variable quantitative (type = INTERVAL) dans le nœud INPUT DATA SOURCE. Ensuite, SEM propose dans le nœud TREE deux types d'arbres : celui dérivé de CART qui choisit les coupures sur une réduction de la variance intra-nœuds, et celui dérivé de CHAID qui choisit les coupures avec un test de Fisher (F test).
La procédure mise en œuvre est la proc ARBORETUM (dans SAS 9) ou la proc DMSPLIT (dans SAS v8). Ces procédures ne sont disponibles qu'avec une licence SAS EM. Donc on ne peut pas les utiliser avec seulement une licence SAS Base ou SAS/STAT. Cependant, ces procédures ont une syntaxe (certes non documentée) donc peuvent être incluses dans des programmes et des macros qu'on exécutera directement depuis SAS PC ou SAS Enterprise Guide.
Bonjour, Suite à une modélisation sous SAS EM (via une régression logistique et arbre de décision), je voudrais "forcer" le type de quelques variables. Celles-ci présentent des valeurs numériques discrètes (par exemple, un nombre de contrats : 0,1,2 ou 3) et lors de la phase de modélisation, EM fait des moyennes de ces chiffres car dans le noeud IDS, elles sont en "interval". Pourtant, pour un client, cela ne veut rien dire d'avoir moins de 0,5 contrat. Les quatre mesures proposées telles BINARY, INTERVAL, NOMINAL ou ORDINAL ne répondent pas au problème de conserver des valeurs entières alors comment puis-je le résoudre ? Merci de votre aide.
Pour votre question de variables discrètes comme un nombre de contrats, il devrait suffire de déclarer sa mesure comme ORDINAL dans le nœud INPUT DATA SOURCE ou, si vous voulez limiter ce changement à certaines branches de votre diagramme, avec un nœud DATA SET ATTRIBUTES.
Bonjour, je suis en stage et je voudrais réaliser un arbre de décision sous SAS. Je voudrais connaître la forme du programme permettant de construire un arbre de décision sous SAS. Merci d'avance
Il n'existe malheureusement pas de programme existant directement dans SAS pour réaliser des arbres de décision. Ceux-ci peuvent être produits avec l'interface SAS Enterprise Miner, qui fait l'objet d'un module facturé en sus.
A partir de SAS 9.4, on peut cependant produire des arbres de décision avec la procédure HPSPLIT de SAS/STAT.
Probleme de discrimination :
Input : n individus sur lesquels sont mesurés p variables numériques. Output : la variable binaire d'intéret. Structure des données : seulement 20% des individus posseèdent la caractéristique binaire. Modele : par exemple un reseau de neurones de type perceptron multicouche.
Question : les individus présentant la valeur 1 (dans 20% des cas) apparaissent naturellement sous représentés dans le jeu de données. Par conséquent, le modèle estimé s'adapte très pauvrement : il prédit dans la grande majorité des cas une valeur = à 0. Quelles sont les techniques existantes pour sur-pondérer la sous population présentant la valeur 1 de la variable binaire d'intéret. La seule que je connaisse etant :répliquer plusieurs fois cette meme sous population, ou utiliser des methodes de type arcing.
Merci d'avance pour la réponse apportée.
La duplication d'individus est toujours dangereuse, sauf quand elle est contrôlée par un mécanisme de type bootstrap, comme dans les méthodes d'arcing.
N'est-il pas préférable de travailler sur un échantillon équilibré (50% de 0, 50% de 1) quitte à réduire la taille de votre échantillon de travail ?
L'emploi d'un arcing (boosting ou bagging) sur ce genre de population donne en général de bons résultats (plus spectaculaires si vous partez d'un modèle moins stable qu'un réseau de neurones, par exemple un arbre de décision).
La méthode choisie (parmi CHAID, CART et C4.5, selon le critère (chi-2, entropie ou information de Gini) choisi dans BASIC) n'a généralement pas vraiment d'influence sur le résultat. Ce qu'il faut regarder, c'est le taux de classement (onglet SUMMARY des sorties) et en particulier sa constance dans les 2 ou 3 jeux de données TRAIN/VALIDATION/TEST (==> robustesse) ; il faut garder à l'esprit qu'en général l'arbre de décision est un mauvais outil prédictif : il découvre bien des niches mais fait un scoring médiocre sur les individus moyens.
Je ne suis pas sûr de bien comprendre ta question, mais s'il s'agit de faire un score il suffit de laisser travailler le noeud "Score !". Il génère une étape Data qui retrace les différentes branches de l'arbre. Sinon, le score (la proba) est calculé comme le pourcentage d'évènements dans la feuille de l'arbre considérée.
Je me pose des questions sur la sélection de variables sous SEM : en effet le test du chi-deux proposé ne semble pas correspondre au test du chi-deux sous SAS (PROC FREQ avec option CHISQ). Qu'en est-il vraiment? je suis allée voir ce que faisait SEM dans le Program Editor et il fait une PROC DMSPLIT : qu'est-ce que c'est que cette PROC ? Dans quel module est-elle disponible ?
En fait, le noeud VARIABLE SELECTION construit un arbre comme le noeud TREE (d'où la proc DMSPLIT qui est en fait celle qui tourne derrière TREE), sur la base de l'algorithme CHAID. Les variables retenues sont donc celles qui sortent les premières dans l'arbre. Cependant, il ne faut pas non plus espérer retrouver exactement le même arbre qu'avec le noeud TREE (hé non, ce serait trop simple !!!), sauf à ne pas avoir de valeurs manquantes dans les données (le noeud VARIABLE SELECTION traite les valeurs manquantes différemment de TREE).
Quand je spécifie une probabilité a priori (Prior proba) dans un noeud Tree, il prend cette proba pour l'échantillon d'apprentissage, de validation et de test. Or moi, ce que je voudrais, c'est qu'il prenne cette proba pour apprendre et qu'il valide et teste sur un échantillon normal. A part dupliquer les individus à qui je veux donner une plus grande importance, comment résoudre ce problème ?
Pas de possibilité (connue de nous au moins) de n'appliquer les probas a priori qu'à l'échantillon d'apprentissage. En fait, ces probas sont considérées comme des coûts (matrice de coût et profit) qui s'appliquent tout le temps. Par contre, l'aide (EM Reference dans le menu Help de SEM) est assez détaillée sur le rôle de ces probas, en plus y a de fort belles images.
Dans SEM, les valeurs manquantes ne sont pas traitées, sauf cas exceptionnel, comme des valeurs ordinaires. Tous les codages de la variable cible sont autorisés, sauf ceux qui incluent une valeur manquante.
Association
Je voudrais savoir dans mon étude si dans le temps il y a un effet de propagation de différents types d'incidents (3 types).
Pour cela j'ai utilisé le noeud "Association" de SEM en mettant la variable temps (date + heure) comme variable séquentielle, la variable type d'incidents comme variable cible et en cochant l'option "sequence". Pouvez-vous m'indiquer ce que fait SAS derrière : est-ce qu'il discrétise la variable temps? Si oui, comment? Quel est le pas de temps (date/ heure / minute...)? Peut-on avoir la main dessus? (ex : choisir le pas de temps heure pour une même date)
Merci d'avance.
Le noeud Association n'utilise la variable séquentielle qu'en tant que numéro d'ordre. Il ne fait donc pas la différence entre une variable numérotée 1,2,3 et une variable temps. Les écarts ne sont pas non plus pris en compte : 1,2,4 est une séquence analogue à 1,2,3.
Le seul moyen de prendre en compte les écarts serait de les inclure en tant qu'items virtuels, sous forme d'intervalle de temps par exemple :
- Achat 1 : lit
- Achat 1 : 1er achat [item virtuel]
- Achat 2 : canapé
- Achat 2 : entre 1 et 3 mois après le 1er achat [item virtuel] Achat 3 : cuisine équipée
- Achat 3 : un an après le 1er achat [item virtuel] Achat 3 : plus de six mois après l'achat précédent [item virtuel] ...
De manière à ce que ces écarts puissent apparaître dans les règles.
Pour le noeud Association :
- rôle ID : un identifiant commande (ou achat) pour reconnaître quels produits sont achetés ENSEMBLE
- rôle FREQ : nombre de produits achetés à la fois, quantité commandée
- rôle TARGET : l'identifiant d'un produit (ou, au niveau agrégé, d'une famille de produits) et les items virtuels (éventuellement : un exemple d'item virtuel est la région d'achat, la présence d'une promotion, la tranche d'âge de l'acheteur, etc...)
Automatisation
FILENAME test EMAIL TYPE = "TEXT/HTML" SUBJECT = "Ceci est un test" ; DATA _NULL_ ; INFILE CARDS DLM = "/" MISSOVER ; FILE test ; INPUT nom :$30. ; nom = UPCASE(nom) ; PUT "!EM_TO! " nom ; DETALINES; contact@od-datamining.com olivier decourt ; RUN ;
proc build catalog = maBib.appliDef ; /* catalogue de l'appli livrée */ merge catalog = maBib.appliDvp /* catalogue de l'appli de développement */ NOSOURCE ; /* source non visible */ run ;
ODS EXCLUDE ALL ; /* plus aucune sortie sauf ODS OUTPUT */ PROC TTEST ... ; ... ODS OUTPUT ... ; RUN ; ODS SELECT ALL ; /* retour à la normale */
ODS OUTPUT ANOVA = work.maTable ; PROC REG DATA = ... ; ... RUN ; QUIT ;
/* partie 1 : modifier le Registry */ data _null_ ; file "c:\temp\regtemp.reg" ; put "[ODS\PREFERENCES\HTML]" / "'AutoNavigate'=int:0" ; run ;
proc registry import = "c:\temp\regtemp.reg" ; run ;
/* étape 2 : le traitement pour lequel on ne veut pas avoir le résultat présenté spontanément */
/* étape 3 : remettre le Registry à sa valeur par défaut */ proc registry uninstall = "c:\temp\regtemp.reg" ; run ;
DM "odsresults ; clear" ;
data ww.CMb; set ww.CM1b ww.CM2b ... ww.CM40b; run;Merci Bonjour, et merci de votre question. Vous pouvez utiliser un programme comme celui-ci :
%MACRO empilement (nbTables) ; DATA ww.CMb ; SET %DO i=1 %TO &nbTables ; ww.CM&i.b %END ; ; RUN ; %MEND empilement ;
%empilement (40)A partir de SAS 9.2, plus besoin de macros ! Vous pouvez écrire directement
SET ww.CM1-ww.CM40 ;dans votre étape Data. Par contre, comme dans votre cas le nom des tables ne se termine pas par un nombre, il faudra rester à la solution macro.
%macro essai(a=); data outpct; set outpct; variable='&a';/*???*/ run; %mend essai;
%essai(a=sonf);Je voudrais en fait que dans ma table outpct apparaisse une variable nommée "variable" dont la modalité serait ici 'sonf'. Comment faire ? Merci d'avance. Il suffit de mettre des doubles guillemets : "&a" , au lieu des simples. Ces derniers bloquent l'action du compilateur macro.
proc tabulate data=data.tab3 missing ; class cat ; class sonf; tables sonf all='Total',cat*(n*f=10.0 pctn='%'*f=10.1) all='Total'*(n*f=10.0 pctn='%'*f=10.1) ; run ;où chaque variable (comme ici "sonf") est traitée en fonction de la variable "cat". Je voudrais à chaque fois récupérer le risque relatif (proc freq option cmh) et sous chaque tableau écrire : "Le risque relatif est : ....". Comment faire? Merci d'avance. voici un exemple de réponse :
- avec une proc Freq (et l'option RELRISK plutôt que CMH plus bavarde), calculer les risques relatifs. Ceux-ci sont édités dans un objet ODS appelé RelativeRisks (si vous utilisez CMH, l'objet se nomme CommonRelRisks)
- ajouter, juste au-dessus de la proc Freq, une instruction ODS OUTPUT pour récupérer ces informations dans une table SAS
- après la proc Freq, ajouter une étape Data pour générer une macro-variable contenant la valeur du risque relatif qui vous intéresse
- se servir de la valeur de cette macro-variable dans un FOOTNOTE ou un ODS TEXT.
ODS EXCLUDE ALL ; ODS OUTPUT relativeRisks = work.rr ; PROC FREQ DATA = cours.produits ; TABLE couleur * primeur / RELRISK ; RUN ; ODS SELECT ALL ; DATA _NULL_ ; SET work.rr (WHERE = (studyType = "Case-Control (Odds Ratio)")) ; CALL SYMPUT ("rr", LEFT(PUT(value, 12.2))) ; RUN ; ODS RTF FILE = "c:\temp\essai.doc" STARTPAGE = NEVER ; PROC TABULATE DATA = cours.produits ; CLASS couleur primeur ; TABLE (couleur ALL="TOTAL") , (primeur ALL="TOTAL") * (N * F = 7. colPctN = "%" * F = 7.1) ; RUN ; ODS RTF TEXT = "Le risque relatif est : &rr" ; ODS RTF CLOSE ;Par rapport au programme de votre question, je préfère l'emploi des mots-clés PCTN, COLPCTN et ROWPCTN à celui des spécifications entre < et > du dénominateur de ces pourcentages ; PCTN sont des pourcentages de l'ensemble du tableau, COLPCTN des pourcentages-colonnes et ROWPCTN des pourcentages-lignes.
%let liste1= a b c ; %let liste2=(a f d) ; %let liste3=;Je souhaite comparer chaque variable de la liste1 avec toutes les variables de la liste2 pour constituer une liste3 excluant de la liste1 les variables figurant dans la liste2 (soit liste3=b c); Ci après le code que j’ai écris
%do i=1 %to &n; %if %scan(&liste1,&i) not in &liste2 %then %do; %let liste3=liste3 %scan(&liste1,&i); %end; %end;NB : n est le nombre d’éléments de la liste1 que j’ai précédemment récupéré. Le pb c’est que ça ne marche pas et ci-après la log : ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was: %scan(&liste1,&i) not in &liste2 Je ne comprends pas cette erreur. Merci d'avance de votre aide. Bonjour. Le problème, c'est qu'avant la version 9 de SAS, l'opérateur IN n'existe pas en macro-langage. Il le prend donc pour du texte et n'arrive pas à évaluer la condition. Par contre, on peut utiliser une fonction comme TRANWRD, qui va remplacer un nom de variable vu dans LISTE2 par un blanc. Après avoir passé tout LISTE2 en revue (TRANWRD n'accepte qu'un mot à la fois à remplacer), on supprime les blancs inutiles pour la beauté du résultat.
%let liste1= a b c ; %let liste2= a f d ; %let liste3=; %MACRO sansListe2 ; %GLOBAL liste3 ; %LET liste3 = &liste1 ; %LET i = 1 ; %DO %WHILE (%SCAN(&liste2,&i) NE ) ; %LET liste1 = %SYSFUNC(TRANWRD(&liste1,%SCAN(&liste2,&i), )) ; %LET i = %EVAL(&i + 1) ; %END ; %LET liste3 = %SYSFUNC(COMPBL(&liste3)) ; %MEND sansListe2 ; %sansListe2 ;
DATA maTable ; SET maTable (RENAME = (v3-v15 = x20-x32)) ; RUN ;Les variables s'appellent à l'origine v3, v4, v5, ..., v15 et après renommage, x20, x21, ..., x32. Sinon, vous pouvez construire une table SAS avec les anciens et les nouveaux noms (éventuellement à partir d'une feuille Excel importée). L'exemple ci-dessous vous montre comment on peut ensuite générer automatiquement la litanie de RENAME.
DATA work.nouveaux_noms ; INPUT ancien $ nouveau $ ; DATALINES ; name nom sex sexe weight poids height taille ; RUN ; %LET table = sashelp.class ; /* NE PLUS RIEN MODIFIER APRES CETTE LIGNE */ DATA _NULL_ ; SET work.nouveaux_noms END = fin ; IF _N_=1 THEN DO ; CALL EXECUTE ("DATA work.nouvelle_table ;") ; CALL EXECUTE ("SET &table (RENAME=(") ; END ; CALL EXECUTE (ancien!!"="!!nouveau) ; IF fin THEN DO ; CALL EXECUTE (")) ;") ; CALL EXECUTE ("RUN ;") ; END ; RUN ;
- Déclarer une bibliothèque sur ce répertoire. LIBNAME ma_macro "c:\temp" ;
- Déclarer à SAS qu'on veut y mettre des macros (ou qu'il y en a déjà là). OPTIONS MSTORED SASMSTORE = ma_macro ;
- Exécuter le macro-programme en modifiant sa PREMIERE ligne : %MACRO mon_macro_programme (parametre1, parametre2, ...) / STORE ; ... %MEND mon_macro_programme ;
%mon_macro_programme (valeur1, valeur2, ...) ;
%IF %SYSEVAL(&seuil.-&ecarty.) > 0 %THEN ...et obtenir un résultat correct !
proc transpose data=infic prefix=cnt out=outfic; var nocnt; by client; run ;va générer cnt1 à cntn. Comment récupérer le nombre de variables générées (n) dans une étape data ? Merci. Pour mettre ce nombre dans une macro-variable, voici un premier programme :
DATA _NULL_ ; SET outfic ; ARRAY transpose cnt: ; CALL SYMPUT ("nbNllesVar", DIM(transpose)) ; STOP ; RUN ;Vous récupérez le nombre de variables créées par la procédure TRANSPOSE dans la macro-variable &nbNllesVar. Pour disposer de ce nombre sous forme de variable dans l'étape Data, il suffit de modifier légèrement ce programme :
DATA ... ; SET outfic ; ARRAY transpose cnt: ; nbVar = DIM(transpose) ; /* il est également possible d'opérer des traitements avec une boucle sur l'Array : DO i = 1 TO DIM(transpose) ; traitement sur transpose(i) END ; */ RUN ;
%LET recherche = ar ; PROC PRINT DATA = sashelp.class ; WHERE soc LIKE "%&recherche%" ; RUN ;Comment résoudre ce problème ? Il faut masquer au macro-compilateur les deux %. Pour cela, on utilisera la macro-fonction %NRQUOTE, qui masque des caractères pendant la phase de résolution (transformation du programme par le macro-compilateur)... Le macro-compilateur n'est donc intéressé que par l'expression &recherche, qui ne pose pas de problème. Il est ensuite transmis le programme correct au compilateur SAS, qui aura le droit de voir les %.
%LET recherche = ar ; PROC PRINT DATA = sashelp.class ; WHERE soc LIKE "%NRQUOTE(%)&recherche%NRQUOTE(%)" ; RUN ;
LIBNAME bib1 "..." ; LIBNAME bib2 "..." ; LIBNAME bibmac (bib1 bib2) ; option SASMSTORE = bibmac MSTORED ;SAS ira d'abord chercher dans le catalogue bib1.sasmacr, puis en cas d'échec (le macro-programme demandé ne s'y trouve pas) dans bib2.sasmacr. L'écriture d'une nouvelle macro se fera dans bib1.sasmacr. Bien sûr, cela marche avec plus de deux bibliothèques.
%if &Nberr=0 %then %do; « arrêter tout » %end ;Si c'est possible comment faire ? Avec les versions de SAS antérieures à la 9, on ne peut traiter le problème qu'à "l'ancienne" avec un %GOTO vers un autre point du programme (après lequel on ne fera plus rien).
%macro MP1 ; %if condition %then %do; %goto exit; %end;
%exit: %mend MP1;Avec la version 9 apparaissent deux instructions %ABORT et %RETURN qui permettent d'arrêter l'exécution du macro-programme. %ABORT arrête le MP avec un message d'erreur tandis que %RETURN arrête le MP sans erreur.
%let i = %eval (&i + 1) ;
%macro essai; data table; input variable; cards; 1 2 3 ; run; %mend essai; %essai; ERROR: The macro ESSAI generated CARDS (data lines) for the DATA step, which could cause incorrect results. The DATA step and the macro will stop executing. NOTE: The data set WORK.TABLE has 0 observations and 1 variables.Bonjour. Effectivement, l'emploi de CARDS, CARDS4 et DATALINES est interdit dans un macro-programme. La raison est sans doute la difficulté prévisible de bien repérer les données proposées. Une alternative sera de mettre les données dans un fichier texte et de le lire avec INFILE ... INPUT.
data _null_; infile "c:\essai.txt" firstobs=2 dlm =','; input a$ b$; run;Bonjour. CALL SYMPUT ne s'applique pas forcément à des tables SAS en dur ; tout ce qui peut être chargé dans le vecteur de travai (PDV) peut être utilisé dans un CALL SYMPUT pour alimenter des macro-variables.
data _null_; infile "c:\essai.txt" firstobs=2 dlm =','; input a$ b$; call symput ("mva",a) ; call symput ("mvb",b) ; run;Ce programme doit fonctionner correctement et vous créer les MV nécessaires.
ODS HTML FILE = "chemin et nom de votre fichier.xls" ; TITLE ; FOOTNOTE ; PROC PRINT DATA = votre_table LABEL NOOBS ; RUN ; ODS HTML CLOSE ;Vous obtiendrez ainsi une pseudo feuille Excel (en fait, c'est une page Web habillée d'une extension XLS, mais Excel 97 n'y verra que du feu). En revanche, pour pouvoir ajouter d'autres feuilles au classeur par la suite, il est recommandé d'ouvrir Excel, d'ouvrir la feuille créée et de la sauvegarder en forçant son type à "Classeur Excel". Plus proprement, mais uniquement si vous possédez le module ACCESS TO PC FILES, vous pouvez exporter directement dans une vraie feuille Excel ainsi :
PROC EXPORT DATA = votre_table OUTFILE = "chemin et nom de votre fichier.xls" REPLACE DBMS = EXCEL97 ; RUN ;Pour savoir si vous possédez ledit module, exécutez le programme suivant :
PROC SETINIT NOALIAS ; RUN ;et regardez dans la Log. Si une ligne "SAS/ACCESS Interface to PC Files" y apparaît (ou un intitulé approchant, il varie selon les versions), c'est bon. Sinon, il faudra opter pour la première solution.
proc corresp data=stage.basefinale outc=corr; tables Nom_DRD naf cible effectif_consolide2 nb_etablissement2 chiffre_affaire2 libelle_Forme_Juridique_Prospect Departement_prospect ; run;Mes questions sont les suivantes : Est-ce que l'ACM effectué ci-dessus est bonne? Et sur quels résultats exactement dois-je réaliser l'analyse discriminante (inertie, mass, dim,....)? Merci d'avance ! Bonjour. Pour pouvoir enchaîner ACM et analyse discriminante, il faut réaliser l'ACM dans l'espace des individus. Or l'instruction TABLES ne permet de se placer que dans l'espace des variables. Vous devez plutôt utiliser l'instruction VAR, et mettre en entrée une table d'indicatrices (à créer avec la procédure Transreg par exemple). Vous trouverez sur notre site une macro SAS pour faire un modèle DISQUAL.
PROC PLOT DATA = tableSAS ; PLOT varY * varX = "#" $ variableTexte ; RUN ; QUIT ;Le signe # sert de marqueur aux points (il peut être remplacé par ce que l'on veut) et variableTexte contient les noms de modalités, identifiants d'individus, etc. A noter qu'à partir de la version 9.1 de SAS, ODS GRAPHICS produit le 1er plan factoriel d'une AFC avec la procédure CORRESP. En revanche, il nécessitera SAS/GRAPH en version 9.2 (et redevient dans SAS/Base à partir de SA 9.3 !!!).
Classification
Bonjour, si le CCC de la proc FASTCLUS est très très négatif, comment puis-je le corriger? J'ai essayé de changer le nombre de classes mais cela ne marche pas.
Bonjour. Les valeurs du CCC supérieures à 3, comme le raconte la doc SAS, sont une rareté sur de vrais jeux de données. En réalité, il arrive souvent qu'on ait des valeurs négatives de l'ordre de plusieurs centaines. L'important est déjà d'observer un pic du CCC pour un nombre de classes (il faut essayer des procédures FASTCLUS avec plusieurs nombres de classes et représenter une courbe avec le nombre de classes en abscisses et le CCC en ordonnées). Vous pouvez aussi essayer de changer l'ordre de la table en entrée de FASTCLUS. Ainsi les points de départ dans la construction des classes seront différents, et les classes finales également.
Bonjour,
Je désire effectuer une CAH sous sas avec la PROC FASTCLUS suivi de la PROC CLUSTER car ma base de données est volumineuse. J'aimerai savoir s'il existe une option permettant de fixer le nombre minimum d’individus acceptés dans chacune des classes afin de ne pas se retrouver avec des classes comportant 10 individus et une autre 5000.
Bonjour.Dans l'instruction PROC FASTCLUS, vous avez une option DELETE= derrière laquelle vous pouvez indiquer la taille minimale d'une classe.
J'ai besoin de faire une classification sur des individus décrits par des variables discrètes. Est-ce qu'il me suffit de travailler sur des indicatrices de ces variables ?
Il serait plus correct d'alimenter la procédure de classification (proc CLUSTER ou FASTCLUS ou les deux) avec les sorties (coordonnées sur les axes factoriels) d'une Analyse des Correspondances Multiples (ACM réalisée avec la proc CORRESP). Comme la proc CORRESP attend un tableau disjonctif complet, on l'alimente effectivement avec des indicatrices. On récupère ensuite les coordonnées des individus sur les axes factoriels avec l'option OUT. Ces coordonnées sont des variables quantitatives : on peut donc les utiliser dans les procs CLUSTER et FASTCLUS.
Je souhaiterais réaliser une classification à l'aide de variables qualitatives. Je dispose de SAS Enterprise Miner et je souhaiterais savoir si ce dernier peut me réaliser ma classification. Et si oui, comment ?
SEM est un peu borné côté variables qualitatives. L'idée serait de lui fournir des variables quanti qui racontent la même chose. Pour ça, il faudrait faire une ACM (proc CORRESP) dans un noeud SAS Code par exemple...
J'ai une base de données avec beaucoup d'individus et 4 variables ( 46 modalités). les variables sont sous la forme d'un tableau disjonctif complet. Je veux effectuer une classification sur les variables. Ici, je ne m'interesse qu'aux variables et non aux individus. Je veux savoir quelles modalités peuvent être regroupées. Comment faire une classification? Il existe peut-être une autre méthode que les classifications ?
Bonjour. Pour trouver des similitudes entre modalités de variables, la technique usuelle est de faire une ACM avec une proc CORRESP, et de regarder l'espace des variables pour y repérer des proximités. Cependant, on peut effectivement imaginer "automatiser" cette recherche avec une classification hiérarchique ; pour les variables quantitatives, SAS propose d'ailleurs la proc VARCLUS qui fait ce genre d'agrégations. Pour réussir quelque chose de semblable sur des données quali, il faut enchaîner une proc CORRESP (pour obtenir les coordonnées factorielles des modalités), une proc CLUSTER (pour la CAH) et une proc TREE (pour afficher l'arbre d'agrégation). D'un point de vue code, ça ressemblerait à :
/* création du tableau disjonctif complet */ PROC TRANSREG DATA=scoring.assur DESIGN NOPRINT ; MODEL CLASS(marque prof c_permis zontarif / ZERO=NONE) ; OUTPUT OUT=work.tdc ; RUN ; /* recuperation des coordonnées factorielles */ ODS OUTPUT colCoors = work.variables ; PROC CORRESP DATA=work.tdc NOROW DIMENS=%EVAL(&_trgindn-4) ; VAR &_trgind ; RUN ; /* CAH */ PROC CLUSTER DATA=work.variables OUTTREE = work.dendo METHOD=WARD ; VAR dim: ; ID label ; RUN ; /* affichage du dendogramme */ PROC TREE DATA=work.dendo HORIZONTAL ; ID label ; RUN ;
Bonjour.
Je veux faire une classification sur les individus d'un tableau disjonctif complet. Pouvez-vous me donner le code sous SAS ? D'avance merci.
Bonjour.Comme votre point de départ est un tableau disjonctif complet, il est préférable de faire une ACM (PROC CORRESP) au préalable. On récupère les coordonnées factorielles des observations dans la table créée par l'option OUTC de la PROC CORRESP (filtrer uniquement les lignes où _TYPE_="OBS"). La procédure CLUSTER construit ensuite une CAH sur les coordonnées factorielles :
PROC CLUSTER DATA = tableSAS OUTTREE = tableDendogramme ; VAR dim: ; RUN ;La table créée par l'option OUTTREE contient les informations nécessaires au dessin du graphique de fusion des classes (dendogramme ou graphique arborescent). On obtient ce dernier par la procédure TREE :
PROC TREE DATA = tableDendogramme ; RUN ;Une fois choisi le bon nombre de classes, vous exécutez une dernière fois la procédure TREE pour obtenir l'affectation des individus aux classes :
PROC TREE DATA = tableDendogramme OUT = tableClassement NCLUSTERS = nbClasses ; RUN ;
Client/serveur
Bonjour, J’ai enregistré l'ensemble des commandes de mon batch dans un fichier txt. Quelles sont ensuite les commandes de lancement? D'avance merci
Bonjour.
Pour lancer un programme SAS en batch, la commande Unix correspond au raccourci qui lance habituellement SAS.
Il faut indiquer le programme à exécuter après l'option -SYSIN, entre guillemets.
Par exemple : "home/pgm/SAS9/sas.exe" -CONFIG "home/pgm/SAS9/SASV9.CFG" -SYSIN "home/users/perso/pgm.txt"
On peut récupérer la Log en indiquant un nom de fichier après l'option -LOG, et on doit indiquer des instructions ODS dans le programme à exécuter pour récupérer aisément les sorties. Si vous utilisez habituellement un autoexec, il est préférable d'indiquer celui-ci au début du programme à exécuter : par exemple :
%INCLUDE "home/users/perso/autoexec.sas" ; /* début du programme soumis en batch... */ DATA work.test ; SET etc.
Bonjour,
je travaille sur serveur et souhaiterais enregistrer mes tables sur le serveur sous un autre format que le format SAS (pour importation sous BO designer par la suite). Merci d'avance.
Bonjour.
Pour l'export vers Business Objects, le type de fichier le plus simple à transmettre depuis SAS est un fichier texte à séparateur tabulation. On peut le produire, avec une version 8 ou supérieure, à l'aide de la procédure EXPORT, comme le titre de votre question le suggérait :
PROC EXPORT DATA = sashelp.class OUTFILE = "~/test.dat" DBMS = TAB ; RUN ;
Le répertoire ~ est la racine de votre compte utilisateur.
L'autre option est d'utiliser un peu de macro-langage et au final une étape Data pour réaliser cet export. Le macro-langage récupère auprès du dictionnaire des données (créé par la PROC CONTENTS) une liste de noms de variable pour l'en-tête du fichier, et une liste de noms de variables pour l'export proprement dit. Ces créations de macro-variables se font dans une procédure SQL. Enfin, une étape Data d'export "classique" avec instructions SET, FILE et PUT, permet d'écrire dans le fichier voulu.
PROC CONTENTS DATA = sashelp.class OUT = work.dico NOPRINT ; RUN ; PROC SQL NOPRINT ; SELECT QUOTE(LEFT(TRIM(name))), LEFT(TRIM(name)) INTO : liste_en_tete SEPARATED BY " '09'x ", liste_variables SEPARATED BY " '09'x " FROM work.dico ORDER BY varnum ; QUIT ; DATA _NULL_ ; SET sashelp.class ; FILE "c:\test.dat" ; IF _N_ = 1 THEN PUT &liste_en_tete ; PUT &liste_variables ; RUN ;
Le charme de ces deux programmes est qu'ils ne nécessitent jamais l'énumération des noms des variables (pratique quand on possède des dizaines ou des centaines de colonnes dans la table à exporter).
Je souhaite allouer une librairie qui pointerait sur des données situées sur un serveur UNIX qui n'est pas celui sur lequel est installé le SAS que j'utilise.Cependant, si cela est utile, le logiciel SAS est installé sur les 2 serveurs.
Y-a-t-il une (ou plusieurs ??) solutions ?
Merci d'avance,
La présence de SAS sur le second serveur évite la solution assez brutale de devoir transférer (via FTP par exemple, ou un FILENAME FTP au mieux) les données d'un serveur à l'autre.
Deux solutions se profilent à ce problème :
- Faire travailler directement le second serveur, celui où se trouvent les données. Un RSUBMIT ... ENDRSUBMIT permet de lui faire effectuer le maximum de traitement. Pour rappatrier ensuite les données obtenues (si le but est de les exploiter sur le "premier" serveur), une procédure DOWNLOAD fera l'affaire. (Les syntaxes sont précisées en fin de réponse.
- La deuxième (et certainement pas dernière) solution consiste à déclarer sur le "premier" serveur une bibliothèque RLS, c'est à dire une image, un pointeur, un lien vers une bibliothèque du second serveur. On considère alors les données de cette bibliothèque comme toutes celles qui se trouvent sur le premier serveur. Les temps de réponse de cette solution seront certainement médiocres. Mais sa simplicité est maximale.
Syntaxe pour le RSUBMIT : RSUBMIT ; PROC xxx ... ; ... RUN ; ENDRSUBMIT ;
Syntaxe pour la proc DOWNLOAD : RSUBMIT ; PROC DOWNLOAD DATA = tableSASserveur2 OUT = tableSASserveur1 ; RUN ; ENDRSUBMIT ;
Syntaxe pour le RLS : RSUBMIT ; LIBNAME toto "chemin" ; ENDRSUBMIT ; LIBNAME Rtoto SLIBREF = toto SERVER = nomDuServeur ;
La démarche suivante pose problème :
- j'ai créé un échantillon sur ma session Unix...
- je l'ai transféré en tant que fichier à plat sur Windows NT
- je l'ai importé sous SEM...
le problème qui se pose : des variables qui étaient dans ma base de départ de type char deviennent de type num... j'ai voulu les modifier dans un noeud IDS mais ça ne fonctionne pas... Y a t-il un autre moyen?
Il s'agit en fait d'un problème d'importation de SAS lui-même, pas spécifique à SEM. Il prend comme numériques toutes les variables n'ayant que des valeurs chiffrées (même s'il s'agit de codes). Le plus simple est peut-être de faire l'import à la main avec une étape Data et une instruction INPUT.
Je travaille en client/serveur. Je crée en RSUBMIT des formats avec une PROC FORMAT. Je fais une option FMTSEARCH sur la librairie qui contient le catalogue de formats. Pour l'exécution de procédures, tout va bien. Mais quand je veux regarder ma table avec l'Explorer, SAS me dit qu'il ne trouve pas les formats. Que se passe-t-il ?
LE PROBLEME : l'architecture client/serveur ne fait pas transiter les formats. Cela implique entre autres qu'on ne peut pas utiliser sur le client les formats du serveur et vice-versa, et que l'on ne peut pas créer sur le serveur des formats depuis le poste client (même dans un RSUBMIT).
LA SOLUTION : Première étape, créer le(s) format(s) en LOCAL. Donc sur le PC. Pour cela, exécuter EN-DEHORS du bloc RSUBMIT / ENDRSUBMIT la procédure formats avec une syntaxe
PROC FORMAT LIB = librairie_locale ; etc... RUN ;
Deuxième étape, le catalogue FORMATS créé dans la librairie locale doit être "remonté" sur le serveur. Pour cela, SUR LE SERVEUR cette fois (dans un bloc RSUBMIT / ENDRSUBMIT), utiliser la PROC UPLOAD qui est dédiée à la copie de "membres" SAS d'une librairie client dans une librairie distante du serveur. Si, par exemple, vous avez stocké les formats dans WORK.FORMATS, vous les remonterez ainsi vers ServLib.FORMATS :
PROC UPLOAD INCAT = WORK.FORMATS OUTCAT = ServLib.FORMATS ; RUN ;
Data Science & Big Data
- la proc ARIMA a une option FORECAST (avec une option LEAD pour indiquer le nombre de périodes pour lesquelles calculer des valeurs) pour créer une table de prévisions
- vous pouvez mettre en œuvre l'équation de prévision dans une étape Data : l'observation à t-1 s'obtient avec la fonction LAG, t-2 avec LAG2, etc., à condition que les observations soient triées par ordre chronologique.
proc arima data=a.s1; identify var=prod(1,12) nlag=24 noprint; estimate q=(1)(12) ; run; quit;ou
proc arima data=a.s1; identify var=prod(1,12) nlag=24 noprint; estimate q=(1)(12) Q=(1)(12) ; run; quit;??? merci Bonjour. On suppose qu'on cherche à estimer un processus SARIMA (p,d,q)(P,D,Q)s. Dans l'instruction ESTIMATE vous devez indiquer P,p, Q et q, avec une syntaxe qui défie un peu la logique : ESTIMATE P=(p)(P) Q=(q Q) ; En revanche, comme SAS ne fait pas de différence entre minuscules et majuscules en dehors des chaînes entre guillemets, peu importe qu'on écrive P= et Q= ou p= et q=. Pour la différentiation et la saisonnalité, c'est l'instruction IDENTIFY qui les décrit, comme dans votre exemple : VAR=série(d,s*D).
- soit vous avez peu de contrats auto récents (mettons quelques centaines seulement) et il faudra probablement ouvrir un petit peu la plage temporelle pour construire une base d'étude avec, au moins, un millier de contrats auto, et un millier de clients n'en ayant pas ;
- soit vous avez déjà, avec les nouveaux clients auto des deux années écoulées, des volumes suffisants, et le risque d'aller chercher les clients plus anciens serait de prendre un compte un profil qui n'est plus ceux des clients qui vous rejoignent actuellement. (Pour des raisons d'évolution de tarifs, de concurrence, d'image, de campagne publicitaire, ceux qui ont souscrit il y a, mettons, 5 ans, ne le feraient peut-être plus chez vous aujourd'hui, et ne restent que par inertie.)
- choisir un seuil pour transformer les prédictions continues (le score) en prédictions binaires (par exemple : 0,5 : si P_1 < 0,5 alors Ypredit = 0, sinon Ypredit=1)
- calculer la nouvelle variable binaire Ypredit
- la croiser (dans une proc Freq) avec la variable Yobservé
- additionner les pourcentages (2e ligne de chaque case) des cellules dans la diagonale du tableau (correspondances entre Yobservé et Y prédit).
CLASS variablesQuali / PARAM = GLM ;donne des coefficients de référence égaux à zéro. C'est le choix par défaut dans GENMOD.
CLASS variablesQuali / PARAM = REF ;donne des contraintes pour que l'ensemble des coefficients d'une variable qualitative soit nul. C'est le choix par défaut dans LOGISTIC.
PROC GLM DATA = tableSAS ; CLASS listeVariablesQuali ; MODEL variableY = listeVariablesQuantiEtQuali / ESTIMATE ; LSMEANS variableQuali / PDIFF=ALL ; RUN ; QUIT ;Une remarque : si le nombre d'observations sur lesquelles vous modélisez est faible, trop de modalités à vos variables qualitatives risquent de faire baisser la robustesse de votre modèle, et alors sans doute faudra-t-il fusionner des modalités... Dans ce cas, les comparaisons 2 à 2 de modalités peuvent vous aider (instruction LSMEANS ci-dessus). Une seconde remarque : si la distribution de vos prix à modéliser suit une loi normale, les procédures REG et GLM sont effectivement appropriées. S'ils suivent plutôt une loi Gamma, il faudra passer à la procédure GENMOD.
- Dans la partie Fit Statistics, on retrouve les critères d'Akaike, de Schwartz et la log-vraisemblance
- Dans la partie Global Tests, on a les tests du chi2 associés au score, à la log-vraisemblance et à la statistique de Wald
MODEL Y = covariables / CTABLE PPROB = (listeDeSeuils) ;
OUTPUT OUT = table PRED = variableP ;on a dans variableP les valeurs prédites pour les données inconnues (ce qu'on appelle un score). Ces valeurs s'échelonnent de 0 à 1, on les lit comme des probabilités d'occurrence d'un évènement. A partir de SAS 9.3, on peut aussi utiliser l'instruction SCORE.
- Type I SS
- Type II SS
- Type III SS
- Types I et III : sommes de carrés sur les EFFETS SIMPLES. C'est à dire la contribution de chacune des variables explicatives, sans les croiser entre elles. Le type I les introduit dans le même ordre que dans l'instruction MODEL, tandis que le type III corrige le biais dû à cet ordre (en fait, c'est comme s'il n'en tenait pas compte).
- Types II : il inclut les effets croisés.
- Type IV : il permet de prendre en compte les données "trouées" (certains cas de figures ne se présentent pas).
ODS TRACE ON / LISTING ; PROC xxx ... ; ... RUN ; ODS TRACE OFF ;Les informations sur chaque objet s'ajoutent dans la fenêtre Output. Une fois qu'on connaît le nom (QUANTILES pour celui qui vous concerne), on peut écire :
PROC UNIVARIATE ... ; ... ODS OUTPUT quantiles = work.maTableSAS ; RUN ;ou, pour n'afficher que le tableau de quantiles :
ODS SELECT quantiles ; PROC UNIVARIATE ... ; ... RUN ; ODS SELECT ALL ;
ODS OUTPUT OddsRatios = nomTableSAS ;Pour fonctionner, il faut que cette instruction soit entre les instructions PROC LOGISTIC et RUN.
ODS EXCLUDE ALL ; /* plus aucune sortie sauf ODS OUTPUT */ PROC TTEST ... ; ... ODS OUTPUT ... ; RUN ; ODS SELECT ALL ; /* retour à la normale */
ODS OUTPUT ANOVA = work.maTable ; PROC REG DATA = ... ; ... RUN ; QUIT ;
ODS OUTPUT parameterEstimates = work.coeffs ;et vous retrouverez dans la table COEFFS de la bibliothèque WORK vos coefficients.
PLOT varY * varX = varGroupe ;permet d'obtenir plusieurs séries de points correspondant à différents groupes d'observations.
SYMBOL i = rl v = dot ; PROC GPLOT DATA = sashelp.class ; PLOT weight * height = sex ; RUN ; QUIT ;
PRELIMINARY RUNS : éventualité de faire un premier ajustement des poids synaptiques (coefficients du réseau) parce qu'on ne trouve pas qu'il arrive correctement au minimum d'erreur possible. Généralement inutile à paramétrer.
TRAINING TECHNIQUE : algorithme cherchant un minimum de la fonction d'erreur. DEFAULT correspond à un algorithme très respecté, LEVENBERG-MARQUARDT. Il est néanmoins très coûteux en temps et en mémoire (il inverse une forme hermitienne de la matrice jacobienne, ça a peu d'importance pour la suite mais dans une conversation ça fait toujours bien !) sur les réseaux très complexes (3 neurones cachés ou plus, plusieurs couches cachées, beaucoup de variables en entrée, variable cible polytomique aux nombreuses valeurs). On lui préfèrera alors le gradient conjugué (CONJUGATE GRADIAN) qui est moins efficace, mais plus rapide. En résumé, ici encore, on peut garder le choix par défaut, sauf pour de gros réseaux.
Quel fonction de transfert utilise SEM pour les réseaux de neurone ? la logistique ?
Il utilise par défaut une tangente hyperbolique dans les perceptrons, une loi normale dans les RBF. Pour modifier cela, aller dans l'onglet ADVANCED, cliquer droit sur la couche cachée et choisir PROPERTIES, puis l'onglet HIDDEN. On a alors le choix pour ACTIVATION FUNCTION : logistique, tangente hyperbolique, gaussienne, arctangente, sinus, cosinus, etc...
Dans la sortie (output), à quoi correspond la table "weights" ? (on a des H11 - H12... cela correspond-il aux noeuds) et comment analyse-t-on le graph dans cet onglet (weight) ?
Il s'agit des poids synaptiques du réseau. On ne peut rien en tirer, si ce n'est l'équation du modèle dans les cas les plus simples (et encore... C'est tellement compliqué qu'on n'en retire aucune info). Le graphique est lui aussi largement inutile. Les sorties du RN de SEM ne se commentent pas vraiment (même pas du tout).
En faisant une modélisation sur SEM avec des réseaux de neurones, on obtient un taux de mal classés de 50% : alors, que doit-on faire ? Arrêter ?
Augmenter la taille de la couche cachée pourrait être une solution. Une deuxième couche cachée n'est utile que si vous avez des relations très très très complexes entre les entrées et les sorties. Sinon, on peut essayer en bougeant la limite du score : par défaut, il décide dans un sens ou dans l'autre autour de la valeur bascule de 0,5. Peut-être qu'on aurait moins de mal classés en décalant cette limite, ou en créant une zone d'incertitude (zone de non-décision).
Y a t'il une aide sous SEM ?
Oui. Il faut aller dans HELP > ENTERPRISE MINER REFERENCE. Elle est très complète (mais tout en anglais). Sur les réseaux de neurones, il y a deux volets, un de théorie des RN et un sur la mise en oeuvre du noeud Neural Network.
J'ai besoin d'utiliser les réseaux de neurones sous SEM. Tout d'abord peut-t-on utiliser une variable "target" avec plusieurs modalités? Je n'ai pas de problèmes pour les lancer mais je ne sais pas trop comment les interpréter, à part le "misclassification rate"... Dans l' "output validation data", il n'y a pas de variables permettant de savoir où les individus ont été classés...
Pas de contre-indication à modéliser une variable continue avec les RN de SAS, l'inconvénient étant la difficulté d'évaluer la qualité du modèle. Et en plus, son opacité est grande (mais c'est toujours le cas avec les RN !). Il n'y a pas grand-chose à tirer des sorties proposées par SAS, et globalement pas grand-chose à y faire. Pour voir les valeurs proposées par SEM, il faut enchaîner un nœud Assessment où on ne fait rien de spécial sinon accepter ce modèle, et un noeud Score qui score la table de départ. Alors on pourra voir les prédictions, et même plus (graphique, procédures statistiques,...) : elles se trouvent dans une table &_SCORE, sous le nom de P_nomDeLaVariableAPrédire. Si tu as une autre variable continue, je propose par exemple ce programme :
symbol1 i=join l=1 ; symbol2 i=join l=2 ; proc gplot data = &_score ; plot (y p_y) * x / overlay ; run ; quit ;
Il n'y a qu'à remplacer les x et les y par les noms de variables Input et Target réciproquement. On peut faire ça dans un noeud SAS Code pour l'intégrer au diagramme (il faut l'enchaîner après le nœud Score) ou directement dans le program editor après exécution du noeud Score.
Je ne trouve pas la même note de score que SEM lors de la régression... En fait moi je considère que quand par exemple sur une variable à 2 modalités l'individu a la modalité 2 le coefficient de cette modalité 2 est égal à zéro alors que SEM prend comme coeff -(le coeff de la modalité 1)... Exemple pour la variable détention de sécurité12, on a 2 modalités sec1 et sec2.. Sur la grille des coefficients, le coeff de sec1=0.23 et dans ce cas si un individu a la modalité 2, SEM va lui mettre un coeff de -0.23 alors que moi je lui mettrais zéro... Ma question est : de quelle théorie sort-il cette règle? et qu'est ce que ça change et qui a raison?
Il s'agit d'une des petites subtilités du noeud régression : il fonctionne selon deux types de codage, donc d'évaluation des paramètres... Le premier, appelé DEVIATION, est celui par défaut. Il contraint la somme des paramètres à faire toujours 0, d'où l'obligation de prendre l'opposé comme coefficient du niveau de référence quand on a une variable binaire. Le second modèle de codage, GLM, est celui qu'on a l'habitude de manipuler. (Y compris dans les procédures REG et LOGISTIC.) Il consiste à mettre 0 pour la modalité de référence, et à donner les autres coeffs en fonction. Comme toujours, sur les fondements théoriques de leurs implémentations, les docs SAS restent d'une louable discrétion. En revanche, comment se débarrasser de ce codage bizarre ? Il suffit de cocher la case INPUT CODING = GLM au lieu du défaut INPUT CODING = DEVIATION. Cela se passe dans l'onglet MODEL OPTIONS, sous-onglet REGRESSION, dans le paramétrage de ce noeud.
Je voudrais changer le répertoire dans lequel se trouve mon projet SEM (déjà assez volumineux). Quels fichiers dois-je transférer ?
Quels fichiers conserver ? Tous ! Par contre, on peut migrer très facilement un projet par copier / coller vers un endroit où vous avez 1) des droits en écriture et 2) de la place.Il suffit de trimbaler tout le petit monde créé par SEM, à savoir :
- les répertoires EMDATA, EMPROJ, REPORTS, ainsi que
- le projet (le .DMP)
- le ou les diagramme(s) (les .DMD).
Comment est ce que je peux récupérer facilement la note du score créé par SEM pour chaque client ?
La note de score de chaque individu se trouve dans les variables P_EVENT, P_NEVENT, P_variableCibleModalité1, P_variableCibleModalité2, etc... (ces derniers noms sont bien sûr tronqués sur 8 ou 32 caractères selon la version de SAS). C'est entre 0 et 1. On trouve cette info une fois fait le scoring, of course, dans la table scorée. Si c'est vous qui avez lancé l'étape Data de scoring (dans le program editor), vous savez le nom de cette table. Si c'est SEM qui a tout fait (noeud Score ! [apply]), c'est dans la table correspondant au contenu de la macro-variable _SCORE. On peut connaître ce contenu en faisant %put &_score ; dans le program editor, et le nom de la table appraîtra dans la log. Reste à l'ouvrir classiquement (proc print, fenêtre Explorer, FSView).
Est-ce normal que pour 100 000 lignes, SEM indique le message d'erreur suivant : out of resources ?
Il ne faut pas trop charger SEM dans une configuration avec un serveur qui n'a pas une grosse capacité. Le mieux, c'est de le faire monter en charge progressivement, pour voir où il casse. Dans l'absolu, je ne peux pas dire "100000 c'est trop" ou "100000 ça devrait passer". D'une fois sur l'autre, je n'ai pas les mêmes résultats sur mon propre PC.
Il faut savoir cependant que SEM demande surtout deux choses : de l'espace disque pour entreposer ses multiples tables temporaires (il faut donc choisir de domicilier son projet dans un endroit où la place libre ne manque pas et où il n'existe pas de quotas) et surtout, pour l'exécution des tâches, de la mémoire vive. Mieux vaut donc une machine (serveur ou PC en "stand-alone", c'est à dire sans faire de client/serveur) avec beaucoup de mémoire vive (ajouter des barettes, fermer les autres applications, etc...) qu'avec un ou plusieurs processeurs très rapides, car la puissance de calcul passe après (il lui faut en tout premier lieu de la place) ; de plus, avant la version 9.0, SAS (et a fortiori SEM) ne sait pas profiter d'un multi-processeur.
Je voudrais faire une régression logistique en utilisant des classes de mes variables quantitatives... Pour cela je peux utiliser le noeud transform variables et calculer des classes selon les quartiles ou quelque chose du genre mais le problème c'est que j'aimerais faire une classe exclusivement = 0 ... car pour les montants par exemple il y en beaucoup qui sont égaux à zéro. Donc je voudrais avoir ma 1ère classe seulement pour des valeurs nulles puis la 2ème par exemple pour des valeurs comprises entre zéro exclus et 12000 F... Comment m'y prendre ?
Pour le problème de découpage en classes : voici une solution à la main, parce qu'on ne peut pas faire mieux sans passer par un macro-programme dans le noeud SAS Code pour le faire automatiquement :
- calculer les valeurs des quantiles. Les noter sur un bout de papier (c'est VRAIMENT une solution à la main !)
- dans Transform Variables, créer une nouvelle variable, dont la définition sera : 1+(VAR>0)+(VAR>12000)+(VAR>20000) par exemple. Remplacer VAR par le nom de la variable quali de départ, et 12000 et 20000 par les quantiles de la feuille de papier.
Les tests entre parenthèses renvoient des booléens : 0 pour faux, 1 pour vrai. SEM produit une variable qui vaut : 1 pour les valeurs nulles, 2 pour les valeurs entre 0 exclus et 12000 inclus, 3 pour les valeurs entre 12000 exclus et 20000 inclus, 4 pour les valeurs > 20000.
Bonjour, pouvez -vous me donner les caractéristiques et les différences entre les logiciels Sas Guide et Sas Entreprise Miner? Peut on faire des scores avec Sas Guide?
Merci beaucoup pour votre réponse.
SAS Enterprise Guide est un logiciel qui génère du code SAS à travers une interface presse-bouton. Il est orienté vers la construction de requêtes (extraction de données, jointures) et la statistique plutôt descriptive (graphiques, stats exploratoires). Il possède des interfaces pour la construction de modèles (régression linéaire, logistique, données de survie) mais pour la construction d'un score, les options ne sont pas très nombreuses. On en vient alors à écrire soi-même le code, en utilisant les procédures Logistic et Discrim disponibles dans le module SAS/STAT. Les graphiques et autres informations complémentaires doivent également être obtenues à la main.
En comparaison, SAS Enterprise Miner est non seulement une interface, mais intègre également des fonctionnalités spécifiques pour le Data Mining, en particulier la construction d'arbres de décision (proc Arboretum), de réseaux de neurones (proc Dmneurl), et même une procédure de régression spécifique (proc Dmreg). A part l'analyse discriminante, toutes les techniques sont directement accessibles dans l'interface de Miner. Les graphiques commentant les résultats sont spontanément construits par le logiciel, de même que les mises en concurrence de méthodes (comparaison de courbes de lift par exemple). SAS Enterprise Miner propose en outre une méthodologie de projet Data Mining, et des fonctionnalités d'échantillonnage, de gestion des valeurs manquantes, de traitement des valeurs extrêmes, de segmentation, etc. qui lui sont entièrement spécifiques.
En résumé : SEG est une surcouche au logiciel SAS permettant de générer des programmes, avec une vocation plutôt généraliste. On peut s'en servir pour construire un score, avec les outils (procédures) usuels de SAS/STAT. SEM est un outil entièrement tourné vers la construction de scores et n'a pas la vocation "tous publics" de Guide.
Bonjour,
je dispose d'une table SAS de la densité d'une variable discréte (modalité + proba) et je voudrais les quantiles mais la proc univariate n'accepte pas des valeurs < 1 dans son option FREQ. Comme j'ai certaines proba trés faibles si je multiplie ma freq par 1000, je risque de perdre de l'info et si je multiplie par un nombre trés grand, la proc TABULATE est limitée ! Y a-t-il une solution pour obtenir les centiles par exemple ?
Merci
Les procédures usuelles de calculs pour les quantiles ne supportent pas vraiment proprement les pondérations décimales (ni Univariate, ni Rank). La solution de contournement vient de la proc KDE, dont ce n'est pas le but premier, mais qui fournit ces calculs en annexe. Il suffit de lui indiquer les ordres des quantiles espérés dans l'instruction UNIVAR pour les lister, et on les récupère avec ODS OUTPUT.
ODS OUTPUT percentiles=work.quantiles ; PROC KDE DATA=sashelp.class ; UNIVAR weight / PERCENTILES=0 TO 100 BY 1 ; RUN ;
Bonjour,
Habituellement, quand je fais une régression, je travaille sur une variable binaire. En amont, je construis donc un échantillon 50-50 (50% de détenteurs // 50% de non détenteurs). Aujourd'hui, je dois réaliser une régression sur une variable continue mais je ne sais pas comment procéder pour réaliser un échantillon. S'agit-il d'un tirage aléatoire ?
Merci d'avance pour votre réponse.
Bonjour.
Pour une régression linéaire, il n'y a pas d'intérêt particulier à pratiquer un échantillonnage "orienté" au préalable. Un échantillon aléatoire est amplement suffisant si vous disposez de données trop volumineuses. En outre, travailler sur de plus faibles volumes de données vous permettra d'avoir des p-values plus réalistes pour les divers tests associés au modèle linéaire (Fisher, coefficients du modèle) que sur des milliers d'observations qui fournissent presque toujours des p-values inférieures à 0,0001.
Deux contraintes sont en revanche très importantes à satisfaire dans le cadre du modèle linéaire :
- la variable Y expliquée doit suivre une loi normale, ou au moins être unimodale (un seul pic de fréquence parmi ses modalités) et à peu près symétrique. Sinon, vous devez la transformer (avec un logarithme par exemple si elle est asymétrique) ou vous tourner vers un modèle linéaire généralisé (PROC GENMOD de SAS) qui vous permettra de préciser une autre loi que la loi normale pour Y ;
- les variables explicatives doivent être autant que possibles indépendantes les unes des autres. Comme dans tous les modèles linéaires, la multicolinéarité engendre de grandes instabilités dans les coefficients du modèle. La procédure REG propose des critères comme le VIF pour évaluer la multicolinéarité, à condition de travailler uniquement sur des variables explicatives quantitatives. Si ce n'est pas le cas et que vous utilisez la PROC GLM, alors une étude préalable des liaisons entre variables (ACM, tests du chi-2) serait la bienvenue.
Bonjour et merci d'avoir répondu à mes précédentes questions.
Ma régression logistique concerne 39 651 individus. J'ai donc, dans un premier temps, effectué un échantillon équilibré à 50/50 et j'obtiens 2 204 individus (car 1 201 ont la modalité cible égale à 1). Par la suite il est nécessaire de réaliser un partitionnement 70/30. On m'a conseillé de prendre 70% pour l'entrainement et 30% pour la validation. Ce que je voudrais savoir c'est comment faire ce partitionnement sous SAS (et non Miner) ? Faut-il que les deux partitions soient elles aussi équilibrées en fonction de la cible (35% -- >0 et 35% -->1 pour l'entrainement et 15% -->0 et 15% -->1 ) ? Et à quel moment la partition à 30% va t-elle intervenir pour la validation ?
D'autre part, pour le seuil optimal, j'obtiendrai forcément 0,5 puisque mon échantillon est équilibré ? Cela n'est pas gênant ?
Le fait de travailler sur 70% des 2 204 individus ne fausse pas le modèle ?
Je vous remercie pour votre réponse.
Bonjour.
Partition 70/30 :
DATA work.train work.valid ; SET maBase ; alea = RANUNI(0) ; IF alea < .7 THEN OUTPUT work.train ; ELSE OUTPUT work.valid ; RUN ;
Seuil optimal :
Il sera sans doute aux alentours de 0,5, pas forcément exactement à cette valeur. En fait, le seuil optimal s'harmonise avec la valeur de la constante du modèle, ce ne sera donc pas faux de travailler ensuite sur une population non équilibrée avec ce seuil.
Volume de données :
70% de 2200 individus, ça en fait encore largement assez, sauf si vous avez 400 variables explicatives dans votre modèle.
Utilisation des données de validation :
On ne construit pas de modèle dessus, on se contente de leur appliquer le moteur de score (c'est à dire qu'on prédit avec le modèle). Et on comparer le taux de bien classés avec celui donné par les données d'entraînement. Ce taux est plus fiable (l'autre est biaisé vers 0), et la constance du taux est signe de robustesse.
Bonjour,
Je souhaiterai savoir comment faire un échantillonnage stratifié (sur une ou plusieurs variables qualitatives) avec la PROC SURVEYLECT comme le fait le noeud SAMPLING de SEM.
Pour cela, il faut trier au préalable la table selon la variable cible de l'étude. Puis déterminer la taille d'un demi-échantillon (ici, 1500 par exemple).
PROC SURVEYSELECT DATA = maTableSAStriée OUT = monEchantillonEquilibré SAMPSIZE = 1500 ; STRATA maVariableCible ; RUN ;
Bonjour,
Est-il possible d'équilibrer automatiquement sous SEM une base de données à partir des modalités de la variable cible. Autrement dit au lieu de choisir manuellement par exemple 50% de clients et 50% de non-clients à partir d'une BD initiale, SEM propose-t-il cette option? De plus, est-il préférable d'équilibrer avant de constituer l'échantillon d'apprentissage et celui de validation ou d'équilibrer chacun des deux échantillons? Quelles sont les procédures automatiques sous SEM?
Merci d'avance de votre réponse.
Oui, c'est possible en utilisant le noeud SAMPLING de SEM.
- Dans l'onglet principal du noeud SAMPLING, choisir le type d'échantillonnage STRATIFIED, et proposer une taille d'échantillon qui ne dépasse pas 2 fois l'effectif le plus faible (clients ou non-clients) ;
- Dans l'onglet STRATIFICATION, choisir d'utiliser la variable cible (client/non-client) en changeant la valeur de l'attribut STATUS (de DON'T USE à USE)
- Dans le sous-onglet OPTIONS (très bien caché en bas à droite de l'onglet STRATIFICATION), sélectionner EQUAL SIZE pour obtenir deux sous-échantillons de même taille.
Il est préférable de modéliser sur des populations équilibrées, d'une manière générale. Il est donc préférable d'avoir des échantillons d'apprentissage et de validation équilibré. L'enchaînement est donc INPUT DATA SOURCE --> SAMPLING --> DATA PARTITION dans SEM.
Suite à une modélisation de variable binaire, j'utilise la PROC LOGISTIC de SAS 8.2. - Pour espérer obtenir de meilleurs résultats, faut-il équilibrer ma population de clients et de non clients? Exemple: expliquer une situation Y=1 alors que 80% de la population étudiée a Y=1, donne-t-il un poids trop important à ce groupe de clients ? - L'équilibre doit-il se faire dans l'échantillon d'apprentissage (70% de la population totale) sans s'en occuper dans l'échantillon test? - Après avoir obtenu les coefficients estimés du modèle sur les variables explicatives significatives dans le journal via la procédure ou sous EM, comment puis-je appliquer ce modèle sur une autre population (présentant évidemment les mêmes variables explicatives) afin de tous les attribuer un score? Suis-je obligée de faire cette étape manuellement ? Merci beaucoup de votre aide.
Il est toujours préférable de travailler sur un échantillon équilibré. Pour pouvoir comparer les performances de votre modèle sur le corpus d'apprentissage et sur celui de test, il est préférable que les deux soient équilibrés.
L'utilisation des coefficients du modèle peut se faire via la procédure SCORE si les variables explicatives de votre modèle sont quantitatives, ou des indicatrices. La prise en compte par la proc SCORE des variables quali est très mauvaise. Sinon, il est possible d'effectuer automatiquement ces manipulations en écrivant un petit macro-programme.
A noter qu'à partir de la version 9, la proc LOGISTIC intègre une instruction pour préciser une table SAS à scorer.
Dans SEM, un point me pose problème : est ce qu'il a moyen de prendre comme critère le fait de maximiser le taux de détention=1. Je m'explique: en fait le score que j'ai obtenu a un bon taux global mais en fait je me suis rendue compte que peu de gens avaient une note de score élevé ce qui correspondrait au fait que le taux de détention=0 bien classés est supérieur à celui de détention=1 alors que j'aimerais favoriser le 2ème taux...
Pour ce problème, en fait, il faut imposer au modèle une matrice de coûts et profits qui met en avant l'importance de modéliser et bien scorer les détenteurs plutôt que les non-détenteurs. L'autre solution consiste à équilibrer l'échantillon (autant de détenteurs que de non-détenteurs).
Quand je spécifie une probabilité a priori (Prior proba) dans un noeud Tree, il prend cette proba pour l'échantillon d'apprentissage, de validation et de test. Or moi, ce que je voudrais, c'est qu'il prenne cette proba pour apprendre et qu'il valide et teste sur un échantillon normal. A part dupliquer les individus à qui je veux donner une plus grande importance, comment résoudre ce problème ?
Pas de possibilité (connue de nous au moins) de n'appliquer les probas a priori qu'à l'échantillon d'apprentissage. En fait, ces probas sont considérées comme des coûts (matrice de coût et profit) qui s'appliquent tout le temps. Par contre, l'aide (EM Reference dans le menu Help de SEM) est assez détaillée sur le rôle de ces probas, en plus y a de fort belles images.
Je dois résoudre un pb de modélisation de personnes qui quittent un opérateur télécom (churn). Cependant, sur 5000 observations seules 700 churned effectivement. Du coup, le modèle apprend très bien les non churner mais pas les autres... Que faire ?
Dans votre problème, je conseille la constitution d'un échantillon équilibré, c'est à dire où le rapport des deux évènements (churn / pas churn) est voisin de 50/50. Dans SEM, faire un échantillon stratifié de 1000 à 1400 personnes, stratifié sur le churn, et où les strates sont à parts égales (onglet STRATIFICATION, sous-onglet OPTIONS : CRITERIA = EQUAL SIZE).
Bonjour, si le CCC de la proc FASTCLUS est très très négatif, comment puis-je le corriger? J'ai essayé de changer le nombre de classes mais cela ne marche pas.
Bonjour. Les valeurs du CCC supérieures à 3, comme le raconte la doc SAS, sont une rareté sur de vrais jeux de données. En réalité, il arrive souvent qu'on ait des valeurs négatives de l'ordre de plusieurs centaines. L'important est déjà d'observer un pic du CCC pour un nombre de classes (il faut essayer des procédures FASTCLUS avec plusieurs nombres de classes et représenter une courbe avec le nombre de classes en abscisses et le CCC en ordonnées). Vous pouvez aussi essayer de changer l'ordre de la table en entrée de FASTCLUS. Ainsi les points de départ dans la construction des classes seront différents, et les classes finales également.
Bonjour,
Je désire effectuer une CAH sous sas avec la PROC FASTCLUS suivi de la PROC CLUSTER car ma base de données est volumineuse. J'aimerai savoir s'il existe une option permettant de fixer le nombre minimum d’individus acceptés dans chacune des classes afin de ne pas se retrouver avec des classes comportant 10 individus et une autre 5000.
Bonjour.Dans l'instruction PROC FASTCLUS, vous avez une option DELETE= derrière laquelle vous pouvez indiquer la taille minimale d'une classe.
J'ai besoin de faire une classification sur des individus décrits par des variables discrètes. Est-ce qu'il me suffit de travailler sur des indicatrices de ces variables ?
Il serait plus correct d'alimenter la procédure de classification (proc CLUSTER ou FASTCLUS ou les deux) avec les sorties (coordonnées sur les axes factoriels) d'une Analyse des Correspondances Multiples (ACM réalisée avec la proc CORRESP). Comme la proc CORRESP attend un tableau disjonctif complet, on l'alimente effectivement avec des indicatrices. On récupère ensuite les coordonnées des individus sur les axes factoriels avec l'option OUT. Ces coordonnées sont des variables quantitatives : on peut donc les utiliser dans les procs CLUSTER et FASTCLUS.
Je souhaiterais réaliser une classification à l'aide de variables qualitatives. Je dispose de SAS Enterprise Miner et je souhaiterais savoir si ce dernier peut me réaliser ma classification. Et si oui, comment ?
SEM est un peu borné côté variables qualitatives. L'idée serait de lui fournir des variables quanti qui racontent la même chose. Pour ça, il faudrait faire une ACM (proc CORRESP) dans un noeud SAS Code par exemple...
Je voudrais savoir dans mon étude si dans le temps il y a un effet de propagation de différents types d'incidents (3 types).
Pour cela j'ai utilisé le noeud "Association" de SEM en mettant la variable temps (date + heure) comme variable séquentielle, la variable type d'incidents comme variable cible et en cochant l'option "sequence". Pouvez-vous m'indiquer ce que fait SAS derrière : est-ce qu'il discrétise la variable temps? Si oui, comment? Quel est le pas de temps (date/ heure / minute...)? Peut-on avoir la main dessus? (ex : choisir le pas de temps heure pour une même date)
Merci d'avance.
Le noeud Association n'utilise la variable séquentielle qu'en tant que numéro d'ordre. Il ne fait donc pas la différence entre une variable numérotée 1,2,3 et une variable temps. Les écarts ne sont pas non plus pris en compte : 1,2,4 est une séquence analogue à 1,2,3.
Le seul moyen de prendre en compte les écarts serait de les inclure en tant qu'items virtuels, sous forme d'intervalle de temps par exemple :
- Achat 1 : lit
- Achat 1 : 1er achat [item virtuel]
- Achat 2 : canapé
- Achat 2 : entre 1 et 3 mois après le 1er achat [item virtuel] Achat 3 : cuisine équipée
- Achat 3 : un an après le 1er achat [item virtuel] Achat 3 : plus de six mois après l'achat précédent [item virtuel] ...
De manière à ce que ces écarts puissent apparaître dans les règles.
Pour le noeud Association :
- rôle ID : un identifiant commande (ou achat) pour reconnaître quels produits sont achetés ENSEMBLE
- rôle FREQ : nombre de produits achetés à la fois, quantité commandée
- rôle TARGET : l'identifiant d'un produit (ou, au niveau agrégé, d'une famille de produits) et les items virtuels (éventuellement : un exemple d'item virtuel est la région d'achat, la présence d'une promotion, la tranche d'âge de l'acheteur, etc...)
Bonjour,
J'aimerais effectuer un arbre de régression, à savoir un arbre avec une cible quantitative. Cela est-il possible avec Sas EM? Et si oui, comment? Les arbres de décisions sont-ils possibles avec Sas Guide ou Sas Base? Merci pour votre aide.
Oui, il est possible d'utiliser SAS EM pour construire des arbres de régression. Pour cela, il suffit de déclarer comme variable cible une variable quantitative (type = INTERVAL) dans le nœud INPUT DATA SOURCE. Ensuite, SEM propose dans le nœud TREE deux types d'arbres : celui dérivé de CART qui choisit les coupures sur une réduction de la variance intra-nœuds, et celui dérivé de CHAID qui choisit les coupures avec un test de Fisher (F test).
La procédure mise en œuvre est la proc ARBORETUM (dans SAS 9) ou la proc DMSPLIT (dans SAS v8). Ces procédures ne sont disponibles qu'avec une licence SAS EM. Donc on ne peut pas les utiliser avec seulement une licence SAS Base ou SAS/STAT. Cependant, ces procédures ont une syntaxe (certes non documentée) donc peuvent être incluses dans des programmes et des macros qu'on exécutera directement depuis SAS PC ou SAS Enterprise Guide.
Bonjour, Suite à une modélisation sous SAS EM (via une régression logistique et arbre de décision), je voudrais "forcer" le type de quelques variables. Celles-ci présentent des valeurs numériques discrètes (par exemple, un nombre de contrats : 0,1,2 ou 3) et lors de la phase de modélisation, EM fait des moyennes de ces chiffres car dans le noeud IDS, elles sont en "interval". Pourtant, pour un client, cela ne veut rien dire d'avoir moins de 0,5 contrat. Les quatre mesures proposées telles BINARY, INTERVAL, NOMINAL ou ORDINAL ne répondent pas au problème de conserver des valeurs entières alors comment puis-je le résoudre ? Merci de votre aide.
Pour votre question de variables discrètes comme un nombre de contrats, il devrait suffire de déclarer sa mesure comme ORDINAL dans le nœud INPUT DATA SOURCE ou, si vous voulez limiter ce changement à certaines branches de votre diagramme, avec un nœud DATA SET ATTRIBUTES.
Bonjour, je suis en stage et je voudrais réaliser un arbre de décision sous SAS. Je voudrais connaître la forme du programme permettant de construire un arbre de décision sous SAS. Merci d'avance
Il n'existe malheureusement pas de programme existant directement dans SAS pour réaliser des arbres de décision. Ceux-ci peuvent être produits avec l'interface SAS Enterprise Miner, qui fait l'objet d'un module facturé en sus.
A partir de SAS 9.4, on peut cependant produire des arbres de décision avec la procédure HPSPLIT de SAS/STAT.
Probleme de discrimination :
Input : n individus sur lesquels sont mesurés p variables numériques. Output : la variable binaire d'intéret. Structure des données : seulement 20% des individus posseèdent la caractéristique binaire. Modele : par exemple un reseau de neurones de type perceptron multicouche.
Question : les individus présentant la valeur 1 (dans 20% des cas) apparaissent naturellement sous représentés dans le jeu de données. Par conséquent, le modèle estimé s'adapte très pauvrement : il prédit dans la grande majorité des cas une valeur = à 0. Quelles sont les techniques existantes pour sur-pondérer la sous population présentant la valeur 1 de la variable binaire d'intéret. La seule que je connaisse etant :répliquer plusieurs fois cette meme sous population, ou utiliser des methodes de type arcing.
Merci d'avance pour la réponse apportée.
La duplication d'individus est toujours dangereuse, sauf quand elle est contrôlée par un mécanisme de type bootstrap, comme dans les méthodes d'arcing.
N'est-il pas préférable de travailler sur un échantillon équilibré (50% de 0, 50% de 1) quitte à réduire la taille de votre échantillon de travail ?
L'emploi d'un arcing (boosting ou bagging) sur ce genre de population donne en général de bons résultats (plus spectaculaires si vous partez d'un modèle moins stable qu'un réseau de neurones, par exemple un arbre de décision).
La méthode choisie (parmi CHAID, CART et C4.5, selon le critère (chi-2, entropie ou information de Gini) choisi dans BASIC) n'a généralement pas vraiment d'influence sur le résultat. Ce qu'il faut regarder, c'est le taux de classement (onglet SUMMARY des sorties) et en particulier sa constance dans les 2 ou 3 jeux de données TRAIN/VALIDATION/TEST (==> robustesse) ; il faut garder à l'esprit qu'en général l'arbre de décision est un mauvais outil prédictif : il découvre bien des niches mais fait un scoring médiocre sur les individus moyens.
Généralement (sauf dans le noeud "Arbre de Décision"), les observations comportant au moins une valeur manquante sont exclues de l'analyse. On peut choisir de les compléter au préalable avec le noeud Replacement, ou avec un noeud SAS Code faisant appel à la PROC MI. Dans le noeud Arbre de Décision, on peut utiliser la valeur manquante comme une valeur à part entière, ou exclure les observations incomplètes comme dans les autres modèles. Pour cela, dans l'onglet BASIC, on coche (ou pas) TREAT MISSING AS AN ACCEPTABLE VALUE.
Je ne suis pas sûr de bien comprendre ta question, mais s'il s'agit de faire un score il suffit de laisser travailler le noeud "Score !". Il génère une étape Data qui retrace les différentes branches de l'arbre. Sinon, le score (la proba) est calculé comme le pourcentage d'évènements dans la feuille de l'arbre considérée.
Je me pose des questions sur la sélection de variables sous SEM : en effet le test du chi-deux proposé ne semble pas correspondre au test du chi-deux sous SAS (PROC FREQ avec option CHISQ). Qu'en est-il vraiment? je suis allée voir ce que faisait SEM dans le Program Editor et il fait une PROC DMSPLIT : qu'est-ce que c'est que cette PROC ? Dans quel module est-elle disponible ?
En fait, le noeud VARIABLE SELECTION construit un arbre comme le noeud TREE (d'où la proc DMSPLIT qui est en fait celle qui tourne derrière TREE), sur la base de l'algorithme CHAID. Les variables retenues sont donc celles qui sortent les premières dans l'arbre. Cependant, il ne faut pas non plus espérer retrouver exactement le même arbre qu'avec le noeud TREE (hé non, ce serait trop simple !!!), sauf à ne pas avoir de valeurs manquantes dans les données (le noeud VARIABLE SELECTION traite les valeurs manquantes différemment de TREE).
Quand je spécifie une probabilité a priori (Prior proba) dans un noeud Tree, il prend cette proba pour l'échantillon d'apprentissage, de validation et de test. Or moi, ce que je voudrais, c'est qu'il prenne cette proba pour apprendre et qu'il valide et teste sur un échantillon normal. A part dupliquer les individus à qui je veux donner une plus grande importance, comment résoudre ce problème ?
Pas de possibilité (connue de nous au moins) de n'appliquer les probas a priori qu'à l'échantillon d'apprentissage. En fait, ces probas sont considérées comme des coûts (matrice de coût et profit) qui s'appliquent tout le temps. Par contre, l'aide (EM Reference dans le menu Help de SEM) est assez détaillée sur le rôle de ces probas, en plus y a de fort belles images.
Dans SEM, les valeurs manquantes ne sont pas traitées, sauf cas exceptionnel, comme des valeurs ordinaires. Tous les codages de la variable cible sont autorisés, sauf ceux qui incluent une valeur manquante.
J'ai une base de données avec beaucoup d'individus et 4 variables ( 46 modalités). les variables sont sous la forme d'un tableau disjonctif complet. Je veux effectuer une classification sur les variables. Ici, je ne m'interesse qu'aux variables et non aux individus. Je veux savoir quelles modalités peuvent être regroupées. Comment faire une classification? Il existe peut-être une autre méthode que les classifications ?
Bonjour. Pour trouver des similitudes entre modalités de variables, la technique usuelle est de faire une ACM avec une proc CORRESP, et de regarder l'espace des variables pour y repérer des proximités. Cependant, on peut effectivement imaginer "automatiser" cette recherche avec une classification hiérarchique ; pour les variables quantitatives, SAS propose d'ailleurs la proc VARCLUS qui fait ce genre d'agrégations. Pour réussir quelque chose de semblable sur des données quali, il faut enchaîner une proc CORRESP (pour obtenir les coordonnées factorielles des modalités), une proc CLUSTER (pour la CAH) et une proc TREE (pour afficher l'arbre d'agrégation). D'un point de vue code, ça ressemblerait à :
/* création du tableau disjonctif complet */ PROC TRANSREG DATA=scoring.assur DESIGN NOPRINT ; MODEL CLASS(marque prof c_permis zontarif / ZERO=NONE) ; OUTPUT OUT=work.tdc ; RUN ; /* recuperation des coordonnées factorielles */ ODS OUTPUT colCoors = work.variables ; PROC CORRESP DATA=work.tdc NOROW DIMENS=%EVAL(&_trgindn-4) ; VAR &_trgind ; RUN ; /* CAH */ PROC CLUSTER DATA=work.variables OUTTREE = work.dendo METHOD=WARD ; VAR dim: ; ID label ; RUN ; /* affichage du dendogramme */ PROC TREE DATA=work.dendo HORIZONTAL ; ID label ; RUN ;
proc corresp data=stage.basefinale outc=corr; tables Nom_DRD naf cible effectif_consolide2 nb_etablissement2 chiffre_affaire2 libelle_Forme_Juridique_Prospect Departement_prospect ; run;Mes questions sont les suivantes : Est-ce que l'ACM effectué ci-dessus est bonne? Et sur quels résultats exactement dois-je réaliser l'analyse discriminante (inertie, mass, dim,....)? Merci d'avance ! Bonjour. Pour pouvoir enchaîner ACM et analyse discriminante, il faut réaliser l'ACM dans l'espace des individus. Or l'instruction TABLES ne permet de se placer que dans l'espace des variables. Vous devez plutôt utiliser l'instruction VAR, et mettre en entrée une table d'indicatrices (à créer avec la procédure Transreg par exemple). Vous trouverez sur notre site une macro SAS pour faire un modèle DISQUAL.
Bonjour, Voilà mon souci : je voudrais faire une Classification sur une énorme base (env 2 millions de lignes). Ce sont des données qualitatives, alors je dois passer par une ACM, donc construire un Tableau Disjonctif Complet (en tout j'ai 3 variables et 11*97*18 modalités). Seulement SAS bloque un peu beaucoup (il a mouliné toute la nuit et n'a pas avancé...)! La proc transreg que vous proposez dans cette FAQ n'est-elle pas appropriée ici? Ma base est-elle trop volumineuse pour un tel traitement? Si oui, comment faire ma classification? Merci beaucoup pour votre éclairage!
Deux pistes à explorer pour que votre traitement puisse se faire dans un temps acceptable (et, vu vos volumes, se faire tout court !).
1) travailler uniquement sur un échantillon : au lieu des 2 millions de lignes, vous pourriez construire une typologie sur seulement 10% d'entre eux, et ensuite chercher les règles de construction des classes (par un modèle statistique, ou plus simplement par une caractérisation univariée) pour dispatcher l'ensemble de vos lignes dans les différentes classes. 2) réduire le nombre de modalités d'une de vos valeurs : 97 valeurs me paraît un nombre un peu excessif. D'autant que cela risque de déséquilibrer fortement l'ACM (les premiers axes se concentreront sur l'information contenue dans cette variable et pas dans les 2 autres) Vous pourriez faire un recodage pour vous ramener à une vingtaine de valeurs ; non seulement ça équilibre l'ACM, mais en plus la taille des fichiers à traiter (tableau disjonctif complet en entrée de la procédure Corresp, et le tableau de Burt qu'elle construit en interne) sera plus raisonnable. Comment faire votre recodage ? Déjà sur des critères métier, je pense. Et également en faisant une ACM sur cette variable uniquement, dans l'espace des variables seulement, de préférence sur un échantillon aléatoire de vos deux millions de lignes. Pour cette ACM préalable, la syntaxe SAS est la suivante :PROC CORRESP DATA = votreTableSAS MCA SHORT ; TABLES votreVariableA97Modalites ; RUN ;
Si vous avez une version 9 de SAS, vous pouvez ajouter les deux instructions suivantes avant la procédure correspondante :
ODS GRAPHICS ON ; ODS HTML FILE = "c:\temp\sorties ACM.htm" GPATH = "c:\temp" (URL=NONE) ; Et ODS HTML CLOSE ;
après l'instruction RUN ; à la fin du programme.
Non seulement vos sorties seront plus jolies dans une page Web (changer éventuellement c:\temp pour un autre répertoire dans les deux options qui y font référence) mais en plus ODS GRAPHICS ajoutera directement le premier plan factoriel dans l'espace des variables : il ne vous reste "qu'à" fusionner les modalités qui sont proches dans ce plan.PROC PLOT DATA = tableSAS ; PLOT varY * varX = "#" $ variableTexte ; RUN ; QUIT ;Le signe # sert de marqueur aux points (il peut être remplacé par ce que l'on veut) et variableTexte contient les noms de modalités, identifiants d'individus, etc. A noter qu'à partir de la version 9.1 de SAS, ODS GRAPHICS produit le 1er plan factoriel d'une AFC avec la procédure CORRESP. En revanche, il nécessitera SAS/GRAPH en version 9.2 (et redevient dans SAS/Base à partir de SA 9.3 !!!).
Bonjour.
Je veux faire une classification sur les individus d'un tableau disjonctif complet. Pouvez-vous me donner le code sous SAS ? D'avance merci.
Bonjour.Comme votre point de départ est un tableau disjonctif complet, il est préférable de faire une ACM (PROC CORRESP) au préalable. On récupère les coordonnées factorielles des observations dans la table créée par l'option OUTC de la PROC CORRESP (filtrer uniquement les lignes où _TYPE_="OBS"). La procédure CLUSTER construit ensuite une CAH sur les coordonnées factorielles :
PROC CLUSTER DATA = tableSAS OUTTREE = tableDendogramme ; VAR dim: ; RUN ;La table créée par l'option OUTTREE contient les informations nécessaires au dessin du graphique de fusion des classes (dendogramme ou graphique arborescent). On obtient ce dernier par la procédure TREE :
PROC TREE DATA = tableDendogramme ; RUN ;Une fois choisi le bon nombre de classes, vous exécutez une dernière fois la procédure TREE pour obtenir l'affectation des individus aux classes :
PROC TREE DATA = tableDendogramme OUT = tableClassement NCLUSTERS = nbClasses ; RUN ;
Bonjour. Que vous ayez deux, trois ou deux cents variables à inclure dans l'ACM n'est pas source de différences dans le programme SAS. Si vous partez d'une table SAS qui est déjà un tableau disjonctif complet, c'est assez simple. Si ce n'est pas le cas, vous pouvez construire un TDC avec la procédure TRANSREG. La procédure CORRESP utilise la syntaxe suivante :
PROC CORRESP DATA = tableau_disjonctif_complet
NOROW=PRINT OUTC = tableSAS_sortie ;
VAR listeVariablesIndicatricesDuTDC ;
RUN ;
Deux remarques :
1) NOROW=PRINT est une option conseillée si vous travaillez sur un nombre important d'observations, elle évite l'édition dans la fenêtre OUTPUT des coordonnées factorielles, cosinus et autres qualités de chaque observation ;
2) si vous avez construit le TDC avec la procédure TRANSREG, la liste des variables indicatrices à spécifier dans VAR est : VAR &_trgind ;
Bonjour, Comment savoir si on doit réaliser un AFC ou une ACP sur un jeu données. Est-ce que SAS est capable de faire le choix tout seul ou y a-t-il un moyen d' effectuer une ACP ou une AFC avec SAS? Merci
Pour choisir, un moyen simple : les ACP se font sur des données exclusivement continues (quantitatives) et les AFC et ACM sur des données discrètes (qualitatives). Si vous avez des variables des deux types, le plus simple est de mettre en tranches les variables quantitatives et de faire une AFC du tout.
SAS ne fait pas le choix pour vous mais propose deux procédures : PRINCOMP pour les ACP, et CORRESP pour les AFC et ACM. Les sorties de ces deux procédures sont assez limitées en intérêt, aussi est-il souvent nécessaire d'enchaîner une série de procédures graphiques pour obtenir des beaux résultats (axes factoriels, projection des individus et des variables dans les plans factoriels, ...).
N'hésitez donc pas à vous intéresser aux tables produites par ces deux procédures (options OUT= et OUTSTAT=) qui vous permettront ensuite d'enchaîner les traitements pour avoir des résultats exploitables.
Dates
dateSAS = DATEPART(dateSPSS + "15oct1582:00:00:00"dt) - 1 ; FORMAT dateSAS DDMMYY10. ;
proc format; value anccrea low- mdy(12,31,2002) = "1- avant 01/2003" mdy(12,31,2002)-mdy(12,31,2004)= "2- entre 2003 et 2004 " mdy(12,31,2004)-high= "3- depuis 2005 " other ="???"; run;et ça
proc format; value anccrea low- '31/12/2002'd = "1- avant 01/2003" ...Merci. La 2e solution n'était pas bien loin du compte. Simplement, la forme de la date entre guillemets doit être JJ puis mois sur 3 lettres en anglais puis année. Comme dans un WHERE.
PROC FORMAT ; VALUE anccrea LOW- '31dec2002'd = "1- avant 01/2003" ... ; RUN ;
Bonjour, J'essaye d'utiliser la fonction week dans mon programme, pour convertir une date en découpage hebdo. Il semble que cette fonction ne soit pas reconnue. Je suis actuellement en SAS V8, est-ce que cette fonction n'est dispo qu'en V9 ? Je vous remercie pour vos réponses. Bonne journée !
Bonjour. Effectivement la fonction WEEK est nouvelle avec la version 9. A l'utilisation, elle nécessite un 2e argument, "V" ou "W" pour indiquer le mode de calcul des numéros de semaine. Les semaines commencent le lundi et la semaine n°1 commence au 1er lundi de janvier. Les jours précédant le 1er lundi de janvier appartiennent à la semaine 52 si on indique "V", ou la semaine 0 avec "W".
En version 8, vous devez utiliser la fonction INTCK qui calcule le nombre de lundis entre 2 dates (WEEK.2 désigne des semaines commençant le lundi) : semaine=INTCK("WEEK.2", MDY(1,1,YEAR(maDate)), maDate) ; Avec cette formule, les jours précédant le 1er lundi de janvier appartiendront à la semaine 0.Bonjour, je dispose d'une table avec des dates sous un certain format. je voudrais savoir comment les afficher via une proc freq sans format, c'est-à-dire en les visualisant sous la forme du nombre de jour depuis le 1er JAN 1960. L'objectif étant de récupérer les dates distinctes de ma table dans une liste, et de boucler dessus. Par avance, merci.
Bonjour.
Pour répondre directement à votre question, ajoutez une instruction FORMAT maVariableDate 6. ; à votre procédure FREQ. Sinon, vous pouvez directement créer une table de dates distinctes avec une procédure SORT avec l'option NODUPKEY, sans avoir besoin de la proc FREQ.
Bonjour. J'ai une date de format $10. (style 10/10/2010) que je voudrais transformer en date DDMMYY10. Merci d'avance de votre réponse.
Bonjour.
Il faudra créer une nouvelle variable, de type numérique ; pour cela, en SQL ou dans une étape Data, la formule sera INPUT(variableExistante, DDMMYY10.) et le résultat sera en nombre de jours depuis le 01/01/1960. Restera ensuite à l'habiller du format date de votre choix.
Bonjour,
j'ai une variable date dans un fichier, et je souhaite faire la répartition en fonction de tranche gérées par un format que je crée... et je n'arrive pas à créer ce format (sans passer par le calcul du nombre de jours correspondants à ma date..)
j'ai essayé ça :
proc format; value anccrea low- mdy(12,31,2002) = "1- avant 01/2003" mdy(12,31,2002)-mdy(12,31,2004)= "2- entre 2003 et 2004 " mdy(12,31,2004)-high= "3- depuis 2005 " other ="???"; run;et ça
proc format; value anccrea low- '31/12/2002'd = "1- avant 01/2003" ...
Merci.
La 2e solution n'était pas bien loin du compte. Simplement, la forme de la date entre guillemets doit être JJ puis mois sur 3 lettres en anglais puis année. Comme dans un WHERE.
PROC FORMAT ; VALUE anccrea LOW- '31dec2002'd = "1- avant 01/2003" ... ; RUN ;
Bonjour.
J'aurais souhaité afficher une date sous la forme suivante : Janvier 2005 (en français, mais sans le numéro du jour).
D'avance merci.
Bonjour.
Si vos données sont sous forme de dates SAS, vous pouvez utiliser :
- les formats "français" de dates de SAS, comme FRADFWDX. qui afficherait 01 janvier 2005 ;
- un format de type particulier, appelé PICTURE, créé par la procédure FORMAT. Dans le cas de votre demande, c'est ce qu'il convient d'utiliser :
PROC FORMAT ; PICTURE testDate LOW - HIGH = '%B %Y' (DATATYPE = DATE) ; RUN ;
Dans cette syntaxe, l'option DATATYPE = DATE permet de spécifier le type de données lues. On peut également avoir deux autres valeurs, TIME et DATETIME.
Les éléments %Y, %B qui composent la valeur affichée sont des mots-clés reconnus de la procédure FORMAT. Les principaux éléments sont :
- %a = jour de la semaine en français sur 3 lettres
- %A = jour de la semaine en français
- %b = mois sur 3 lettres en français
- %B = mois en français
- %d = jour du mois sans zéro initial
- %0d = jour du mois sur deux chiffres
- %j = jour de l'année (de 1 à 366)
- %m = mois (1 à 12) sans zéro initial
- %0m = mois sur deux chiffres
- %0y = année sur deux chiffres
- %Y = année sur quatre chiffres
Enfin, il est recommandé d'employer des apostrophes et non des guillemets autour de la valeur formatée afin d'éviter toute intervention du compilateur macro.
Comment positionner des lignes concernant le même identifiant les unes à la suite des autres ? Par ex:
identifiant | nom | prenom | date naissance |
111 | durand | paul | 01/10/1987 |
111 | durand | guy | 26/01/1999 |
111 | durand | pierre | 13/09/2001 |
333 | dupont | jack | 16/12/2004 |
Le problème est de positionner la famille durand , identifiant 111, sur la même ligne. Je vous remercie.
Bonjour, et merci de votre question.
Ce genre de "pivotage" de données n'est pas simple, et SAS ne fait pas grand-chose pour nous y aider. Il faut utiliser la procédure TRANSPOSE, sur chacune des variables à pivoter (ici, PRENOM et DATE DE NAISSANCE. On obtient plusieurs tables que l'on combinera dans une étape Data, avec plusieurs instructions SET. Le programme suivant résume les manipulations à effectuer...
DATA work.test ; INPUT id nom $ prenom $ dtnais DDMMYY10. groupe_sanguin $ ; CARDS ; 111 durand paul 01/10/1987 AB 111 durand guy 26/01/1999 A 111 durand pierre 13/09/2001 A 111 durand karl 14/10/2002 O 111 durand marie 14/10/2002 A 111 durand ulysse 25/01/2004 B 111 durand éléonore 25/01/2004 A 111 durand garance 25/01/2004 B 111 durand télémaque 25/01/2004 AB 111 durand vanessa 07/09/2005 A 111 durand armelle 07/09/2005 O 333 dupont jack 16/12/2004 AB ; RUN ; PROC SORT DATA = work.test ; BY id nom ; RUN ; PROC TRANSPOSE DATA = work.test OUT = work.res1 (DROP = _NAME_) PREFIX = prenom ; BY id nom ; VAR prenom ; RUN ; PROC TRANSPOSE DATA = work.test OUT = work.res2 (DROP = _NAME_) PREFIX = dtnais ; BY id nom ; VAR dtnais ; FORMAT dtnais DDMMYY10. ; RUN ; PROC TRANSPOSE DATA = work.test OUT = work.res3 (DROP = _NAME_) PREFIX = gpe_sanguin ; BY id nom ; VAR groupe_sanguin ; RUN ; DATA work.fus ; SET work.res1 ; SET work.res2 ; SET work.res3 ; BY id nom ; RUN ;
Je tiens à remercier Bernard Gestin de m'avoir soufflé cette solution plus simple que celle que j'avais proposée initialement.
Bonjour.
Dans une table SAS que j'ai récupérée, j'ai une variable qui contient manifestement une date, qui semble numérique sur une longueur de 8, mais elle a un aspect bizarre. Une valeur, par exemple, est : 14JUN1977:00:00:00. Les fonctions dates habituelles (YEAR, INTNX, etc.) me renvoient des résultats aberrants quand je les applique à cette variable. Que faire ?
D'avance merci.
Vous êtes en présence d'une variable de "type" Datetime (stockée en nombre de secondes depuis le 01/01/1960 à minuit). C'est donc bien du numérique sur 8 octets (8 octets ça permet de stocker des entiers énormes). Mais ce n'est pas une DATE au sens où les fonctions comme YEAR s'y attendent, c'est à dire un nombre de jours depuis le 01/01/1960. Quant à son aspect "bizarre", il s'explique par un format DATETIME. spécialement conçu pour ce type d'information.
La fonction DATEPART permet d'extraire la partie "date" d'un Datetime. Mais il faut bien penser à affecter un format date (DDMMYY10. par exemple) à la variable ainsi créée.
Une étape Data comme celle-ci résoud le problème :
DATA ma_nouvelle_table ; SET mon_ancienne_table ; variable_date = DATEPART(variable_datetime) ; FORMAT variable_date DDMMYY10. ; RUN ;
(Il convient bien sûr de changer les noms des tables et des variables pour coller à votre sujet.)
Je voudrais savoir dans mon étude si dans le temps il y a un effet de propagation de différents types d'incidents (3 types).
Pour cela j'ai utilisé le noeud "Association" de SEM en mettant la variable temps (date + heure) comme variable séquentielle, la variable type d'incidents comme variable cible et en cochant l'option "sequence". Pouvez-vous m'indiquer ce que fait SAS derrière : est-ce qu'il discrétise la variable temps? Si oui, comment? Quel est le pas de temps (date/ heure / minute...)? Peut-on avoir la main dessus? (ex : choisir le pas de temps heure pour une même date)
Merci d'avance.
Le noeud Association n'utilise la variable séquentielle qu'en tant que numéro d'ordre. Il ne fait donc pas la différence entre une variable numérotée 1,2,3 et une variable temps. Les écarts ne sont pas non plus pris en compte : 1,2,4 est une séquence analogue à 1,2,3.
Le seul moyen de prendre en compte les écarts serait de les inclure en tant qu'items virtuels, sous forme d'intervalle de temps par exemple :
- Achat 1 : lit
- Achat 1 : 1er achat [item virtuel]
- Achat 2 : canapé
- Achat 2 : entre 1 et 3 mois après le 1er achat [item virtuel] Achat 3 : cuisine équipée
- Achat 3 : un an après le 1er achat [item virtuel] Achat 3 : plus de six mois après l'achat précédent [item virtuel] ...
De manière à ce que ces écarts puissent apparaître dans les règles.
Echantillons
Bonjour,
je dispose d'une table SAS de la densité d'une variable discréte (modalité + proba) et je voudrais les quantiles mais la proc univariate n'accepte pas des valeurs < 1 dans son option FREQ. Comme j'ai certaines proba trés faibles si je multiplie ma freq par 1000, je risque de perdre de l'info et si je multiplie par un nombre trés grand, la proc TABULATE est limitée ! Y a-t-il une solution pour obtenir les centiles par exemple ?
Merci
Les procédures usuelles de calculs pour les quantiles ne supportent pas vraiment proprement les pondérations décimales (ni Univariate, ni Rank). La solution de contournement vient de la proc KDE, dont ce n'est pas le but premier, mais qui fournit ces calculs en annexe. Il suffit de lui indiquer les ordres des quantiles espérés dans l'instruction UNIVAR pour les lister, et on les récupère avec ODS OUTPUT.
ODS OUTPUT percentiles=work.quantiles ; PROC KDE DATA=sashelp.class ; UNIVAR weight / PERCENTILES=0 TO 100 BY 1 ; RUN ;
Bonjour,
Habituellement, quand je fais une régression, je travaille sur une variable binaire. En amont, je construis donc un échantillon 50-50 (50% de détenteurs // 50% de non détenteurs). Aujourd'hui, je dois réaliser une régression sur une variable continue mais je ne sais pas comment procéder pour réaliser un échantillon. S'agit-il d'un tirage aléatoire ?
Merci d'avance pour votre réponse.
Bonjour.
Pour une régression linéaire, il n'y a pas d'intérêt particulier à pratiquer un échantillonnage "orienté" au préalable. Un échantillon aléatoire est amplement suffisant si vous disposez de données trop volumineuses. En outre, travailler sur de plus faibles volumes de données vous permettra d'avoir des p-values plus réalistes pour les divers tests associés au modèle linéaire (Fisher, coefficients du modèle) que sur des milliers d'observations qui fournissent presque toujours des p-values inférieures à 0,0001.
Deux contraintes sont en revanche très importantes à satisfaire dans le cadre du modèle linéaire :
- la variable Y expliquée doit suivre une loi normale, ou au moins être unimodale (un seul pic de fréquence parmi ses modalités) et à peu près symétrique. Sinon, vous devez la transformer (avec un logarithme par exemple si elle est asymétrique) ou vous tourner vers un modèle linéaire généralisé (PROC GENMOD de SAS) qui vous permettra de préciser une autre loi que la loi normale pour Y ;
- les variables explicatives doivent être autant que possibles indépendantes les unes des autres. Comme dans tous les modèles linéaires, la multicolinéarité engendre de grandes instabilités dans les coefficients du modèle. La procédure REG propose des critères comme le VIF pour évaluer la multicolinéarité, à condition de travailler uniquement sur des variables explicatives quantitatives. Si ce n'est pas le cas et que vous utilisez la PROC GLM, alors une étude préalable des liaisons entre variables (ACM, tests du chi-2) serait la bienvenue.
Bonjour et merci d'avoir répondu à mes précédentes questions.
Ma régression logistique concerne 39 651 individus. J'ai donc, dans un premier temps, effectué un échantillon équilibré à 50/50 et j'obtiens 2 204 individus (car 1 201 ont la modalité cible égale à 1). Par la suite il est nécessaire de réaliser un partitionnement 70/30. On m'a conseillé de prendre 70% pour l'entrainement et 30% pour la validation. Ce que je voudrais savoir c'est comment faire ce partitionnement sous SAS (et non Miner) ? Faut-il que les deux partitions soient elles aussi équilibrées en fonction de la cible (35% -- >0 et 35% -->1 pour l'entrainement et 15% -->0 et 15% -->1 ) ? Et à quel moment la partition à 30% va t-elle intervenir pour la validation ?
D'autre part, pour le seuil optimal, j'obtiendrai forcément 0,5 puisque mon échantillon est équilibré ? Cela n'est pas gênant ?
Le fait de travailler sur 70% des 2 204 individus ne fausse pas le modèle ?
Je vous remercie pour votre réponse.
Bonjour.
Partition 70/30 :
DATA work.train work.valid ; SET maBase ; alea = RANUNI(0) ; IF alea < .7 THEN OUTPUT work.train ; ELSE OUTPUT work.valid ; RUN ;
Seuil optimal :
Il sera sans doute aux alentours de 0,5, pas forcément exactement à cette valeur. En fait, le seuil optimal s'harmonise avec la valeur de la constante du modèle, ce ne sera donc pas faux de travailler ensuite sur une population non équilibrée avec ce seuil.
Volume de données :
70% de 2200 individus, ça en fait encore largement assez, sauf si vous avez 400 variables explicatives dans votre modèle.
Utilisation des données de validation :
On ne construit pas de modèle dessus, on se contente de leur appliquer le moteur de score (c'est à dire qu'on prédit avec le modèle). Et on comparer le taux de bien classés avec celui donné par les données d'entraînement. Ce taux est plus fiable (l'autre est biaisé vers 0), et la constance du taux est signe de robustesse.
Bonjour,
Je souhaiterai savoir comment faire un échantillonnage stratifié (sur une ou plusieurs variables qualitatives) avec la PROC SURVEYLECT comme le fait le noeud SAMPLING de SEM.
Pour cela, il faut trier au préalable la table selon la variable cible de l'étude. Puis déterminer la taille d'un demi-échantillon (ici, 1500 par exemple).
PROC SURVEYSELECT DATA = maTableSAStriée OUT = monEchantillonEquilibré SAMPSIZE = 1500 ; STRATA maVariableCible ; RUN ;
Bonjour,
Est-il possible d'équilibrer automatiquement sous SEM une base de données à partir des modalités de la variable cible. Autrement dit au lieu de choisir manuellement par exemple 50% de clients et 50% de non-clients à partir d'une BD initiale, SEM propose-t-il cette option? De plus, est-il préférable d'équilibrer avant de constituer l'échantillon d'apprentissage et celui de validation ou d'équilibrer chacun des deux échantillons? Quelles sont les procédures automatiques sous SEM?
Merci d'avance de votre réponse.
Oui, c'est possible en utilisant le noeud SAMPLING de SEM.
- Dans l'onglet principal du noeud SAMPLING, choisir le type d'échantillonnage STRATIFIED, et proposer une taille d'échantillon qui ne dépasse pas 2 fois l'effectif le plus faible (clients ou non-clients) ;
- Dans l'onglet STRATIFICATION, choisir d'utiliser la variable cible (client/non-client) en changeant la valeur de l'attribut STATUS (de DON'T USE à USE)
- Dans le sous-onglet OPTIONS (très bien caché en bas à droite de l'onglet STRATIFICATION), sélectionner EQUAL SIZE pour obtenir deux sous-échantillons de même taille.
Il est préférable de modéliser sur des populations équilibrées, d'une manière générale. Il est donc préférable d'avoir des échantillons d'apprentissage et de validation équilibré. L'enchaînement est donc INPUT DATA SOURCE --> SAMPLING --> DATA PARTITION dans SEM.
Dans SEM, un point me pose problème : est ce qu'il a moyen de prendre comme critère le fait de maximiser le taux de détention=1. Je m'explique: en fait le score que j'ai obtenu a un bon taux global mais en fait je me suis rendue compte que peu de gens avaient une note de score élevé ce qui correspondrait au fait que le taux de détention=0 bien classés est supérieur à celui de détention=1 alors que j'aimerais favoriser le 2ème taux...
Pour ce problème, en fait, il faut imposer au modèle une matrice de coûts et profits qui met en avant l'importance de modéliser et bien scorer les détenteurs plutôt que les non-détenteurs. L'autre solution consiste à équilibrer l'échantillon (autant de détenteurs que de non-détenteurs).
Je dois résoudre un pb de modélisation de personnes qui quittent un opérateur télécom (churn). Cependant, sur 5000 observations seules 700 churned effectivement. Du coup, le modèle apprend très bien les non churner mais pas les autres... Que faire ?
Dans votre problème, je conseille la constitution d'un échantillon équilibré, c'est à dire où le rapport des deux évènements (churn / pas churn) est voisin de 50/50. Dans SEM, faire un échantillon stratifié de 1000 à 1400 personnes, stratifié sur le churn, et où les strates sont à parts égales (onglet STRATIFICATION, sous-onglet OPTIONS : CRITERIA = EQUAL SIZE).
Probleme de discrimination :
Input : n individus sur lesquels sont mesurés p variables numériques. Output : la variable binaire d'intéret. Structure des données : seulement 20% des individus posseèdent la caractéristique binaire. Modele : par exemple un reseau de neurones de type perceptron multicouche.
Question : les individus présentant la valeur 1 (dans 20% des cas) apparaissent naturellement sous représentés dans le jeu de données. Par conséquent, le modèle estimé s'adapte très pauvrement : il prédit dans la grande majorité des cas une valeur = à 0. Quelles sont les techniques existantes pour sur-pondérer la sous population présentant la valeur 1 de la variable binaire d'intéret. La seule que je connaisse etant :répliquer plusieurs fois cette meme sous population, ou utiliser des methodes de type arcing.
Merci d'avance pour la réponse apportée.
La duplication d'individus est toujours dangereuse, sauf quand elle est contrôlée par un mécanisme de type bootstrap, comme dans les méthodes d'arcing.
N'est-il pas préférable de travailler sur un échantillon équilibré (50% de 0, 50% de 1) quitte à réduire la taille de votre échantillon de travail ?
L'emploi d'un arcing (boosting ou bagging) sur ce genre de population donne en général de bons résultats (plus spectaculaires si vous partez d'un modèle moins stable qu'un réseau de neurones, par exemple un arbre de décision).
Bonjour, Voilà mon souci : je voudrais faire une Classification sur une énorme base (env 2 millions de lignes). Ce sont des données qualitatives, alors je dois passer par une ACM, donc construire un Tableau Disjonctif Complet (en tout j'ai 3 variables et 11*97*18 modalités). Seulement SAS bloque un peu beaucoup (il a mouliné toute la nuit et n'a pas avancé...)! La proc transreg que vous proposez dans cette FAQ n'est-elle pas appropriée ici? Ma base est-elle trop volumineuse pour un tel traitement? Si oui, comment faire ma classification? Merci beaucoup pour votre éclairage!
Deux pistes à explorer pour que votre traitement puisse se faire dans un temps acceptable (et, vu vos volumes, se faire tout court !).
1) travailler uniquement sur un échantillon : au lieu des 2 millions de lignes, vous pourriez construire une typologie sur seulement 10% d'entre eux, et ensuite chercher les règles de construction des classes (par un modèle statistique, ou plus simplement par une caractérisation univariée) pour dispatcher l'ensemble de vos lignes dans les différentes classes. 2) réduire le nombre de modalités d'une de vos valeurs : 97 valeurs me paraît un nombre un peu excessif. D'autant que cela risque de déséquilibrer fortement l'ACM (les premiers axes se concentreront sur l'information contenue dans cette variable et pas dans les 2 autres) Vous pourriez faire un recodage pour vous ramener à une vingtaine de valeurs ; non seulement ça équilibre l'ACM, mais en plus la taille des fichiers à traiter (tableau disjonctif complet en entrée de la procédure Corresp, et le tableau de Burt qu'elle construit en interne) sera plus raisonnable. Comment faire votre recodage ? Déjà sur des critères métier, je pense. Et également en faisant une ACM sur cette variable uniquement, dans l'espace des variables seulement, de préférence sur un échantillon aléatoire de vos deux millions de lignes. Pour cette ACM préalable, la syntaxe SAS est la suivante :PROC CORRESP DATA = votreTableSAS MCA SHORT ; TABLES votreVariableA97Modalites ; RUN ;
Si vous avez une version 9 de SAS, vous pouvez ajouter les deux instructions suivantes avant la procédure correspondante :
ODS GRAPHICS ON ; ODS HTML FILE = "c:\temp\sorties ACM.htm" GPATH = "c:\temp" (URL=NONE) ; Et ODS HTML CLOSE ;
après l'instruction RUN ; à la fin du programme.
Non seulement vos sorties seront plus jolies dans une page Web (changer éventuellement c:\temp pour un autre répertoire dans les deux options qui y font référence) mais en plus ODS GRAPHICS ajoutera directement le premier plan factoriel dans l'espace des variables : il ne vous reste "qu'à" fusionner les modalités qui sont proches dans ce plan.Enterprise guide
Bonjour, pouvez -vous me donner les caractéristiques et les différences entre les logiciels Sas Guide et Sas Entreprise Miner? Peut on faire des scores avec Sas Guide?
Merci beaucoup pour votre réponse.
SAS Enterprise Guide est un logiciel qui génère du code SAS à travers une interface presse-bouton. Il est orienté vers la construction de requêtes (extraction de données, jointures) et la statistique plutôt descriptive (graphiques, stats exploratoires). Il possède des interfaces pour la construction de modèles (régression linéaire, logistique, données de survie) mais pour la construction d'un score, les options ne sont pas très nombreuses. On en vient alors à écrire soi-même le code, en utilisant les procédures Logistic et Discrim disponibles dans le module SAS/STAT. Les graphiques et autres informations complémentaires doivent également être obtenues à la main.
En comparaison, SAS Enterprise Miner est non seulement une interface, mais intègre également des fonctionnalités spécifiques pour le Data Mining, en particulier la construction d'arbres de décision (proc Arboretum), de réseaux de neurones (proc Dmneurl), et même une procédure de régression spécifique (proc Dmreg). A part l'analyse discriminante, toutes les techniques sont directement accessibles dans l'interface de Miner. Les graphiques commentant les résultats sont spontanément construits par le logiciel, de même que les mises en concurrence de méthodes (comparaison de courbes de lift par exemple). SAS Enterprise Miner propose en outre une méthodologie de projet Data Mining, et des fonctionnalités d'échantillonnage, de gestion des valeurs manquantes, de traitement des valeurs extrêmes, de segmentation, etc. qui lui sont entièrement spécifiques.
En résumé : SEG est une surcouche au logiciel SAS permettant de générer des programmes, avec une vocation plutôt généraliste. On peut s'en servir pour construire un score, avec les outils (procédures) usuels de SAS/STAT. SEM est un outil entièrement tourné vers la construction de scores et n'a pas la vocation "tous publics" de Guide.
Enterprise Miner
PRELIMINARY RUNS : éventualité de faire un premier ajustement des poids synaptiques (coefficients du réseau) parce qu'on ne trouve pas qu'il arrive correctement au minimum d'erreur possible. Généralement inutile à paramétrer.
TRAINING TECHNIQUE : algorithme cherchant un minimum de la fonction d'erreur. DEFAULT correspond à un algorithme très respecté, LEVENBERG-MARQUARDT. Il est néanmoins très coûteux en temps et en mémoire (il inverse une forme hermitienne de la matrice jacobienne, ça a peu d'importance pour la suite mais dans une conversation ça fait toujours bien !) sur les réseaux très complexes (3 neurones cachés ou plus, plusieurs couches cachées, beaucoup de variables en entrée, variable cible polytomique aux nombreuses valeurs). On lui préfèrera alors le gradient conjugué (CONJUGATE GRADIAN) qui est moins efficace, mais plus rapide. En résumé, ici encore, on peut garder le choix par défaut, sauf pour de gros réseaux.
Quel fonction de transfert utilise SEM pour les réseaux de neurone ? la logistique ?
Il utilise par défaut une tangente hyperbolique dans les perceptrons, une loi normale dans les RBF. Pour modifier cela, aller dans l'onglet ADVANCED, cliquer droit sur la couche cachée et choisir PROPERTIES, puis l'onglet HIDDEN. On a alors le choix pour ACTIVATION FUNCTION : logistique, tangente hyperbolique, gaussienne, arctangente, sinus, cosinus, etc...
Dans la sortie (output), à quoi correspond la table "weights" ? (on a des H11 - H12... cela correspond-il aux noeuds) et comment analyse-t-on le graph dans cet onglet (weight) ?
Il s'agit des poids synaptiques du réseau. On ne peut rien en tirer, si ce n'est l'équation du modèle dans les cas les plus simples (et encore... C'est tellement compliqué qu'on n'en retire aucune info). Le graphique est lui aussi largement inutile. Les sorties du RN de SEM ne se commentent pas vraiment (même pas du tout).
Y a t'il une aide sous SEM ?
Oui. Il faut aller dans HELP > ENTERPRISE MINER REFERENCE. Elle est très complète (mais tout en anglais). Sur les réseaux de neurones, il y a deux volets, un de théorie des RN et un sur la mise en oeuvre du noeud Neural Network.
J'ai besoin d'utiliser les réseaux de neurones sous SEM. Tout d'abord peut-t-on utiliser une variable "target" avec plusieurs modalités? Je n'ai pas de problèmes pour les lancer mais je ne sais pas trop comment les interpréter, à part le "misclassification rate"... Dans l' "output validation data", il n'y a pas de variables permettant de savoir où les individus ont été classés...
Pas de contre-indication à modéliser une variable continue avec les RN de SAS, l'inconvénient étant la difficulté d'évaluer la qualité du modèle. Et en plus, son opacité est grande (mais c'est toujours le cas avec les RN !). Il n'y a pas grand-chose à tirer des sorties proposées par SAS, et globalement pas grand-chose à y faire. Pour voir les valeurs proposées par SEM, il faut enchaîner un nœud Assessment où on ne fait rien de spécial sinon accepter ce modèle, et un noeud Score qui score la table de départ. Alors on pourra voir les prédictions, et même plus (graphique, procédures statistiques,...) : elles se trouvent dans une table &_SCORE, sous le nom de P_nomDeLaVariableAPrédire. Si tu as une autre variable continue, je propose par exemple ce programme :
symbol1 i=join l=1 ; symbol2 i=join l=2 ; proc gplot data = &_score ; plot (y p_y) * x / overlay ; run ; quit ;
Il n'y a qu'à remplacer les x et les y par les noms de variables Input et Target réciproquement. On peut faire ça dans un noeud SAS Code pour l'intégrer au diagramme (il faut l'enchaîner après le nœud Score) ou directement dans le program editor après exécution du noeud Score.
Je ne trouve pas la même note de score que SEM lors de la régression... En fait moi je considère que quand par exemple sur une variable à 2 modalités l'individu a la modalité 2 le coefficient de cette modalité 2 est égal à zéro alors que SEM prend comme coeff -(le coeff de la modalité 1)... Exemple pour la variable détention de sécurité12, on a 2 modalités sec1 et sec2.. Sur la grille des coefficients, le coeff de sec1=0.23 et dans ce cas si un individu a la modalité 2, SEM va lui mettre un coeff de -0.23 alors que moi je lui mettrais zéro... Ma question est : de quelle théorie sort-il cette règle? et qu'est ce que ça change et qui a raison?
Il s'agit d'une des petites subtilités du noeud régression : il fonctionne selon deux types de codage, donc d'évaluation des paramètres... Le premier, appelé DEVIATION, est celui par défaut. Il contraint la somme des paramètres à faire toujours 0, d'où l'obligation de prendre l'opposé comme coefficient du niveau de référence quand on a une variable binaire. Le second modèle de codage, GLM, est celui qu'on a l'habitude de manipuler. (Y compris dans les procédures REG et LOGISTIC.) Il consiste à mettre 0 pour la modalité de référence, et à donner les autres coeffs en fonction. Comme toujours, sur les fondements théoriques de leurs implémentations, les docs SAS restent d'une louable discrétion. En revanche, comment se débarrasser de ce codage bizarre ? Il suffit de cocher la case INPUT CODING = GLM au lieu du défaut INPUT CODING = DEVIATION. Cela se passe dans l'onglet MODEL OPTIONS, sous-onglet REGRESSION, dans le paramétrage de ce noeud.
Je voudrais changer le répertoire dans lequel se trouve mon projet SEM (déjà assez volumineux). Quels fichiers dois-je transférer ?
Quels fichiers conserver ? Tous ! Par contre, on peut migrer très facilement un projet par copier / coller vers un endroit où vous avez 1) des droits en écriture et 2) de la place.Il suffit de trimbaler tout le petit monde créé par SEM, à savoir :
- les répertoires EMDATA, EMPROJ, REPORTS, ainsi que
- le projet (le .DMP)
- le ou les diagramme(s) (les .DMD).
Comment est ce que je peux récupérer facilement la note du score créé par SEM pour chaque client ?
La note de score de chaque individu se trouve dans les variables P_EVENT, P_NEVENT, P_variableCibleModalité1, P_variableCibleModalité2, etc... (ces derniers noms sont bien sûr tronqués sur 8 ou 32 caractères selon la version de SAS). C'est entre 0 et 1. On trouve cette info une fois fait le scoring, of course, dans la table scorée. Si c'est vous qui avez lancé l'étape Data de scoring (dans le program editor), vous savez le nom de cette table. Si c'est SEM qui a tout fait (noeud Score ! [apply]), c'est dans la table correspondant au contenu de la macro-variable _SCORE. On peut connaître ce contenu en faisant %put &_score ; dans le program editor, et le nom de la table appraîtra dans la log. Reste à l'ouvrir classiquement (proc print, fenêtre Explorer, FSView).
Est-ce normal que pour 100 000 lignes, SEM indique le message d'erreur suivant : out of resources ?
Il ne faut pas trop charger SEM dans une configuration avec un serveur qui n'a pas une grosse capacité. Le mieux, c'est de le faire monter en charge progressivement, pour voir où il casse. Dans l'absolu, je ne peux pas dire "100000 c'est trop" ou "100000 ça devrait passer". D'une fois sur l'autre, je n'ai pas les mêmes résultats sur mon propre PC.
Il faut savoir cependant que SEM demande surtout deux choses : de l'espace disque pour entreposer ses multiples tables temporaires (il faut donc choisir de domicilier son projet dans un endroit où la place libre ne manque pas et où il n'existe pas de quotas) et surtout, pour l'exécution des tâches, de la mémoire vive. Mieux vaut donc une machine (serveur ou PC en "stand-alone", c'est à dire sans faire de client/serveur) avec beaucoup de mémoire vive (ajouter des barettes, fermer les autres applications, etc...) qu'avec un ou plusieurs processeurs très rapides, car la puissance de calcul passe après (il lui faut en tout premier lieu de la place) ; de plus, avant la version 9.0, SAS (et a fortiori SEM) ne sait pas profiter d'un multi-processeur.
Je voudrais faire une régression logistique en utilisant des classes de mes variables quantitatives... Pour cela je peux utiliser le noeud transform variables et calculer des classes selon les quartiles ou quelque chose du genre mais le problème c'est que j'aimerais faire une classe exclusivement = 0 ... car pour les montants par exemple il y en beaucoup qui sont égaux à zéro. Donc je voudrais avoir ma 1ère classe seulement pour des valeurs nulles puis la 2ème par exemple pour des valeurs comprises entre zéro exclus et 12000 F... Comment m'y prendre ?
Pour le problème de découpage en classes : voici une solution à la main, parce qu'on ne peut pas faire mieux sans passer par un macro-programme dans le noeud SAS Code pour le faire automatiquement :
- calculer les valeurs des quantiles. Les noter sur un bout de papier (c'est VRAIMENT une solution à la main !)
- dans Transform Variables, créer une nouvelle variable, dont la définition sera : 1+(VAR>0)+(VAR>12000)+(VAR>20000) par exemple. Remplacer VAR par le nom de la variable quali de départ, et 12000 et 20000 par les quantiles de la feuille de papier.
Les tests entre parenthèses renvoient des booléens : 0 pour faux, 1 pour vrai. SEM produit une variable qui vaut : 1 pour les valeurs nulles, 2 pour les valeurs entre 0 exclus et 12000 inclus, 3 pour les valeurs entre 12000 exclus et 20000 inclus, 4 pour les valeurs > 20000.
Bonjour, pouvez -vous me donner les caractéristiques et les différences entre les logiciels Sas Guide et Sas Entreprise Miner? Peut on faire des scores avec Sas Guide?
Merci beaucoup pour votre réponse.
SAS Enterprise Guide est un logiciel qui génère du code SAS à travers une interface presse-bouton. Il est orienté vers la construction de requêtes (extraction de données, jointures) et la statistique plutôt descriptive (graphiques, stats exploratoires). Il possède des interfaces pour la construction de modèles (régression linéaire, logistique, données de survie) mais pour la construction d'un score, les options ne sont pas très nombreuses. On en vient alors à écrire soi-même le code, en utilisant les procédures Logistic et Discrim disponibles dans le module SAS/STAT. Les graphiques et autres informations complémentaires doivent également être obtenues à la main.
En comparaison, SAS Enterprise Miner est non seulement une interface, mais intègre également des fonctionnalités spécifiques pour le Data Mining, en particulier la construction d'arbres de décision (proc Arboretum), de réseaux de neurones (proc Dmneurl), et même une procédure de régression spécifique (proc Dmreg). A part l'analyse discriminante, toutes les techniques sont directement accessibles dans l'interface de Miner. Les graphiques commentant les résultats sont spontanément construits par le logiciel, de même que les mises en concurrence de méthodes (comparaison de courbes de lift par exemple). SAS Enterprise Miner propose en outre une méthodologie de projet Data Mining, et des fonctionnalités d'échantillonnage, de gestion des valeurs manquantes, de traitement des valeurs extrêmes, de segmentation, etc. qui lui sont entièrement spécifiques.
En résumé : SEG est une surcouche au logiciel SAS permettant de générer des programmes, avec une vocation plutôt généraliste. On peut s'en servir pour construire un score, avec les outils (procédures) usuels de SAS/STAT. SEM est un outil entièrement tourné vers la construction de scores et n'a pas la vocation "tous publics" de Guide.
Bonjour,
Je souhaiterai savoir comment faire un échantillonnage stratifié (sur une ou plusieurs variables qualitatives) avec la PROC SURVEYLECT comme le fait le noeud SAMPLING de SEM.
Pour cela, il faut trier au préalable la table selon la variable cible de l'étude. Puis déterminer la taille d'un demi-échantillon (ici, 1500 par exemple).
PROC SURVEYSELECT DATA = maTableSAStriée OUT = monEchantillonEquilibré SAMPSIZE = 1500 ; STRATA maVariableCible ; RUN ;
Dans SEM, un point me pose problème : est ce qu'il a moyen de prendre comme critère le fait de maximiser le taux de détention=1. Je m'explique: en fait le score que j'ai obtenu a un bon taux global mais en fait je me suis rendue compte que peu de gens avaient une note de score élevé ce qui correspondrait au fait que le taux de détention=0 bien classés est supérieur à celui de détention=1 alors que j'aimerais favoriser le 2ème taux...
Pour ce problème, en fait, il faut imposer au modèle une matrice de coûts et profits qui met en avant l'importance de modéliser et bien scorer les détenteurs plutôt que les non-détenteurs. L'autre solution consiste à équilibrer l'échantillon (autant de détenteurs que de non-détenteurs).
Quand je spécifie une probabilité a priori (Prior proba) dans un noeud Tree, il prend cette proba pour l'échantillon d'apprentissage, de validation et de test. Or moi, ce que je voudrais, c'est qu'il prenne cette proba pour apprendre et qu'il valide et teste sur un échantillon normal. A part dupliquer les individus à qui je veux donner une plus grande importance, comment résoudre ce problème ?
Pas de possibilité (connue de nous au moins) de n'appliquer les probas a priori qu'à l'échantillon d'apprentissage. En fait, ces probas sont considérées comme des coûts (matrice de coût et profit) qui s'appliquent tout le temps. Par contre, l'aide (EM Reference dans le menu Help de SEM) est assez détaillée sur le rôle de ces probas, en plus y a de fort belles images.
Je souhaiterais réaliser une classification à l'aide de variables qualitatives. Je dispose de SAS Enterprise Miner et je souhaiterais savoir si ce dernier peut me réaliser ma classification. Et si oui, comment ?
SEM est un peu borné côté variables qualitatives. L'idée serait de lui fournir des variables quanti qui racontent la même chose. Pour ça, il faudrait faire une ACM (proc CORRESP) dans un noeud SAS Code par exemple...
Je voudrais savoir dans mon étude si dans le temps il y a un effet de propagation de différents types d'incidents (3 types).
Pour cela j'ai utilisé le noeud "Association" de SEM en mettant la variable temps (date + heure) comme variable séquentielle, la variable type d'incidents comme variable cible et en cochant l'option "sequence". Pouvez-vous m'indiquer ce que fait SAS derrière : est-ce qu'il discrétise la variable temps? Si oui, comment? Quel est le pas de temps (date/ heure / minute...)? Peut-on avoir la main dessus? (ex : choisir le pas de temps heure pour une même date)
Merci d'avance.
Le noeud Association n'utilise la variable séquentielle qu'en tant que numéro d'ordre. Il ne fait donc pas la différence entre une variable numérotée 1,2,3 et une variable temps. Les écarts ne sont pas non plus pris en compte : 1,2,4 est une séquence analogue à 1,2,3.
Le seul moyen de prendre en compte les écarts serait de les inclure en tant qu'items virtuels, sous forme d'intervalle de temps par exemple :
- Achat 1 : lit
- Achat 1 : 1er achat [item virtuel]
- Achat 2 : canapé
- Achat 2 : entre 1 et 3 mois après le 1er achat [item virtuel] Achat 3 : cuisine équipée
- Achat 3 : un an après le 1er achat [item virtuel] Achat 3 : plus de six mois après l'achat précédent [item virtuel] ...
De manière à ce que ces écarts puissent apparaître dans les règles.
Pour le noeud Association :
- rôle ID : un identifiant commande (ou achat) pour reconnaître quels produits sont achetés ENSEMBLE
- rôle FREQ : nombre de produits achetés à la fois, quantité commandée
- rôle TARGET : l'identifiant d'un produit (ou, au niveau agrégé, d'une famille de produits) et les items virtuels (éventuellement : un exemple d'item virtuel est la région d'achat, la présence d'une promotion, la tranche d'âge de l'acheteur, etc...)
Bonjour,
J'aimerais effectuer un arbre de régression, à savoir un arbre avec une cible quantitative. Cela est-il possible avec Sas EM? Et si oui, comment? Les arbres de décisions sont-ils possibles avec Sas Guide ou Sas Base? Merci pour votre aide.
Oui, il est possible d'utiliser SAS EM pour construire des arbres de régression. Pour cela, il suffit de déclarer comme variable cible une variable quantitative (type = INTERVAL) dans le nœud INPUT DATA SOURCE. Ensuite, SEM propose dans le nœud TREE deux types d'arbres : celui dérivé de CART qui choisit les coupures sur une réduction de la variance intra-nœuds, et celui dérivé de CHAID qui choisit les coupures avec un test de Fisher (F test).
La procédure mise en œuvre est la proc ARBORETUM (dans SAS 9) ou la proc DMSPLIT (dans SAS v8). Ces procédures ne sont disponibles qu'avec une licence SAS EM. Donc on ne peut pas les utiliser avec seulement une licence SAS Base ou SAS/STAT. Cependant, ces procédures ont une syntaxe (certes non documentée) donc peuvent être incluses dans des programmes et des macros qu'on exécutera directement depuis SAS PC ou SAS Enterprise Guide.
Bonjour, Suite à une modélisation sous SAS EM (via une régression logistique et arbre de décision), je voudrais "forcer" le type de quelques variables. Celles-ci présentent des valeurs numériques discrètes (par exemple, un nombre de contrats : 0,1,2 ou 3) et lors de la phase de modélisation, EM fait des moyennes de ces chiffres car dans le noeud IDS, elles sont en "interval". Pourtant, pour un client, cela ne veut rien dire d'avoir moins de 0,5 contrat. Les quatre mesures proposées telles BINARY, INTERVAL, NOMINAL ou ORDINAL ne répondent pas au problème de conserver des valeurs entières alors comment puis-je le résoudre ? Merci de votre aide.
Pour votre question de variables discrètes comme un nombre de contrats, il devrait suffire de déclarer sa mesure comme ORDINAL dans le nœud INPUT DATA SOURCE ou, si vous voulez limiter ce changement à certaines branches de votre diagramme, avec un nœud DATA SET ATTRIBUTES.
Probleme de discrimination :
Input : n individus sur lesquels sont mesurés p variables numériques. Output : la variable binaire d'intéret. Structure des données : seulement 20% des individus posseèdent la caractéristique binaire. Modele : par exemple un reseau de neurones de type perceptron multicouche.
Question : les individus présentant la valeur 1 (dans 20% des cas) apparaissent naturellement sous représentés dans le jeu de données. Par conséquent, le modèle estimé s'adapte très pauvrement : il prédit dans la grande majorité des cas une valeur = à 0. Quelles sont les techniques existantes pour sur-pondérer la sous population présentant la valeur 1 de la variable binaire d'intéret. La seule que je connaisse etant :répliquer plusieurs fois cette meme sous population, ou utiliser des methodes de type arcing.
Merci d'avance pour la réponse apportée.
La duplication d'individus est toujours dangereuse, sauf quand elle est contrôlée par un mécanisme de type bootstrap, comme dans les méthodes d'arcing.
N'est-il pas préférable de travailler sur un échantillon équilibré (50% de 0, 50% de 1) quitte à réduire la taille de votre échantillon de travail ?
L'emploi d'un arcing (boosting ou bagging) sur ce genre de population donne en général de bons résultats (plus spectaculaires si vous partez d'un modèle moins stable qu'un réseau de neurones, par exemple un arbre de décision).
La méthode choisie (parmi CHAID, CART et C4.5, selon le critère (chi-2, entropie ou information de Gini) choisi dans BASIC) n'a généralement pas vraiment d'influence sur le résultat. Ce qu'il faut regarder, c'est le taux de classement (onglet SUMMARY des sorties) et en particulier sa constance dans les 2 ou 3 jeux de données TRAIN/VALIDATION/TEST (==> robustesse) ; il faut garder à l'esprit qu'en général l'arbre de décision est un mauvais outil prédictif : il découvre bien des niches mais fait un scoring médiocre sur les individus moyens.
Généralement (sauf dans le noeud "Arbre de Décision"), les observations comportant au moins une valeur manquante sont exclues de l'analyse. On peut choisir de les compléter au préalable avec le noeud Replacement, ou avec un noeud SAS Code faisant appel à la PROC MI. Dans le noeud Arbre de Décision, on peut utiliser la valeur manquante comme une valeur à part entière, ou exclure les observations incomplètes comme dans les autres modèles. Pour cela, dans l'onglet BASIC, on coche (ou pas) TREAT MISSING AS AN ACCEPTABLE VALUE.
Je ne suis pas sûr de bien comprendre ta question, mais s'il s'agit de faire un score il suffit de laisser travailler le noeud "Score !". Il génère une étape Data qui retrace les différentes branches de l'arbre. Sinon, le score (la proba) est calculé comme le pourcentage d'évènements dans la feuille de l'arbre considérée.
Je me pose des questions sur la sélection de variables sous SEM : en effet le test du chi-deux proposé ne semble pas correspondre au test du chi-deux sous SAS (PROC FREQ avec option CHISQ). Qu'en est-il vraiment? je suis allée voir ce que faisait SEM dans le Program Editor et il fait une PROC DMSPLIT : qu'est-ce que c'est que cette PROC ? Dans quel module est-elle disponible ?
En fait, le noeud VARIABLE SELECTION construit un arbre comme le noeud TREE (d'où la proc DMSPLIT qui est en fait celle qui tourne derrière TREE), sur la base de l'algorithme CHAID. Les variables retenues sont donc celles qui sortent les premières dans l'arbre. Cependant, il ne faut pas non plus espérer retrouver exactement le même arbre qu'avec le noeud TREE (hé non, ce serait trop simple !!!), sauf à ne pas avoir de valeurs manquantes dans les données (le noeud VARIABLE SELECTION traite les valeurs manquantes différemment de TREE).
Quand je spécifie une probabilité a priori (Prior proba) dans un noeud Tree, il prend cette proba pour l'échantillon d'apprentissage, de validation et de test. Or moi, ce que je voudrais, c'est qu'il prenne cette proba pour apprendre et qu'il valide et teste sur un échantillon normal. A part dupliquer les individus à qui je veux donner une plus grande importance, comment résoudre ce problème ?
Pas de possibilité (connue de nous au moins) de n'appliquer les probas a priori qu'à l'échantillon d'apprentissage. En fait, ces probas sont considérées comme des coûts (matrice de coût et profit) qui s'appliquent tout le temps. Par contre, l'aide (EM Reference dans le menu Help de SEM) est assez détaillée sur le rôle de ces probas, en plus y a de fort belles images.
Dans SEM, les valeurs manquantes ne sont pas traitées, sauf cas exceptionnel, comme des valeurs ordinaires. Tous les codages de la variable cible sont autorisés, sauf ceux qui incluent une valeur manquante.
Exportation
- pour que les titres des instructions TITLE apparaissent en tête de chaque onglet; ajoutez l'option EMBEDDED_TITLES="YES" aux spécifications d'ODS TAGSETS.EXCELXP
- si vous souhaitez conserver un titre visible à l'impression, vous pouvez l'indiquer avec l'option PRINT_HEADER="ici titre personnalisé", toujours dans l'instruction ODS TAGSETS.EXCELXP.
ODS TAGSETS.EXCELXP FILE="c:\temp\titres.xls" OPTIONS(EMBEDDED_TITLES="YES" PRINT_HEADER="%NRSTR(&E)Tout le classeur porte sur la table SASHELP.CLASS" SHEET_NAME="Détail" SHEET_INTERVAL="PROC") ; TITLE1 "Liste des enfants" ; PROC PRINT DATA=sashelp.class NOOBS ; RUN ; ODS TAGSETS.EXCELXP OPTIONS(SHEET_NAME="Stats") ; TITLE1 "Statistiques" ; PROC FREQ DATA=sashelp.class ; TABLE sex age ; RUN ; TITLE ; ODS TAGSETS.EXCELXP CLOSE ;
ODS RTF FILE="c:\temp\test vertical.doc" ; PROC REPORT DATA=sashelp.shoes SPLIT=" " NOWD ; COLUMNS _ALL_ ; RUN ; ODS RTF CLOSE ;Ici l'espace sert d'indication pour revenir à la ligne, mais on peut modifier les labels pour incruster à l'endroit voulu (y compris après chaque lettre !) un caractère de retour à la ligne.
PROC CONTENTS DATA=sashelp.shoes OUT=work.labels (KEEP=name label) NOPRINT ; RUN ; DATA _NULL_ ; SET work.labels END=fin ; LENGTH newLabel $ 200 ; newLabel = PRXCHANGE("s/(.)/¤$1/",-1,STRIP(COALESCEC(label,name))) ; newLabel = SUBSTR(newLabel,2) ; /* élimine le 1er ¤ ajouté en tête */ IF _N_=1 THEN CALL EXECUTE ("DATA work.export ; SET sashelp.shoes ; LABEL ") ; CALL EXECUTE (name !! "=" !! QUOTE(STRIP(newLabel))) ; IF fin THEN CALL EXECUTE ("; RUN ;") ; RUN ; ODS RTF FILE="c:\temp\test vertical.doc" ; PROC REPORT DATA=work.export SPLIT="¤" NOWD ; COLUMNS _ALL_ ; RUN ; ODS RTF CLOSE ;
/* pour un classeur Excel : */ PROC EXPORT DATA = votreTable OUTFILE = "chemin et nom du fichier créé" DMBS = EXCEL ; RUN ; /* pour un fichier texte à séparateur tabulation */ PROC EXPORT DATA = votreTable OUTFILE = "chemin et nom du fichier créé" DMBS = DLM ; DELIMITER = "09"x ; RUN ;
proc template; define style styles.noborder; parent=styles.minimal; style Pays / just = center; end; run; ODS HTML FILE='Edition.xls' STYLE=styles.noborder; title; Proc print data=final noobs; Run; ods HTML close ;Merci d'avance. Je vous conseillerais d'aller agir directement dans la procédure Print, qui le permet, plutôt que dans la procédure Template, qui accepte mal les cas particuliers de mise en forme par colonne.
ODS HTML FILE='Edition.xls' STYLE=minimal ; TITLE ; PROC PRINT DATA=final NOOBS ; VAR entite ; VAR pays / STYLE = [JUST=CENTER] ; VAR ; RUN ; ODS HTML CLOSE ;Attention cependant, selon les versions, Excel n'applique pas toujours les consignes de centrage. Si vous possédez SAS 9 et Excel 2003, je vous conseille plutôt de passer par la destination ODS TAGSETS.EXCELXP que par ODS HTML.
ODS ODS TAGSETS.EXCELXP FILE='Edition.xls' STYLE=minimal ; title; Proc print data=final noobs; VAR entite ; VAR pays / STYLE = [JUST=CENTER] ; VAR ; Run; ods ODS TAGSETS.EXCELXP close ;
- soit la création de classeurs au format XML si tu as Excel 2003 ou plus récent pour les relire (il y a des macros en ce sens sur Internet, par exemple sur le site de Richard deVenezia) ;
- soit avec SAS PC et un lien DDE (écriture "en live" vers une feuille Excel déjà ouverte)
- pour toutes versions de SAS depuis la 8.0, vous pouvez ouvrir une destination ODS HTML sur le même principe qu'ODS RTF, en indiquant dans FILE= un fichier dont l'extension est .XLS. Vous ne créerez pas une feuille Excel au sens strict, mais une page Web qu'Excel sait lire à partir de la version 1997
- pour SAS 9.1 et Excel 2003 minimum, vous pouvez utiliser ODS TAGSETS.EXCELXP qui va créer un (presque) véritable classeur Excel. La documentation sur cette destination et ses options peut s'afficher dans la fenêtre Log en exécutant le programme suivant :
ODS TAGSETS.EXCELXP OPTIONS(DOC="help") FILE = "c:\temp\rien.xls" ;
- pour SAS 9.4 et Excel 2007 minimum, vous pouvez utiliser ODS EXCEL qui va créer un véritable classeur Excel d'extension XLSX.
filename sortie DDE "excel|Feuil1!l1c2:l1c79" notab; DATA _null_; SET pgm; FILE sortie; PUT COL1 '09'x COL2 '09'x COL3 '09'x COL4 '09'x COL5 '09'x COL6 '09'x COL7 '09'x COL8 '09'x COL9 '09'x COL10 '09'x COL11 '09'x COL12 '09'x COL13 '09'x COL14 '09'x COL15 '09'x COL16 '09'x COL17 '09'x COL18 '09'x COL19 '09'x COL20 '09'x COL21 '09'x COL22 '09'x COL23 '09'x COL24 '09'x COL25 '09'x COL26 '09'x COL27 '09'x COL28 '09'x COL29 '09'x COL30 '09'x COL31 '09'x COL32 '09'x COL33 '09'x COL34 '09'x COL35 '09'x COL36 '09'x COL37 '09'x COL38 '09'x COL39 '09'x COL40 '09'x COL41 '09'x COL42 '09'x COL43 '09'x COL44 '09'x COL45 '09'x COL46 '09'x COL47 '09'x COL48 '09'x COL49 '09'x COL50 '09'x COL51 '09'x COL52 '09'x COL53 '09'x COL54 '09'x COL55 '09'x COL56 '09'x COL57 '09'x COL58 '09'x COL59 '09'x COL60 '09'x COL61 '09'x COL62 '09'x COL63 '09'x COL64 '09'x COL65 '09'x COL66 '09'x COL67 '09'x COL68 '09'x COL69 '09'x COL70 '09'x COL71 '09'x COL72 '09'x COL73 '09'x COL74 '09'x COL75 '09'x COL76 '09'x COL77 '09'x COL78 '09'x; RUN;Or, sur ma feuille Excel, seules les 22 premières variables sont inscrites. Si je diminue le format de mes variables au minimum (format 3.2), j’arrive à obtenir les 64 premières variables. Mais j’ai toujours une perte d’informations… Comment puis-je faire ? Le problème vient de la largeur du "tuyau" utilisé par SAS pour envoyer les infos à Excel ; par défaut, il ne fait que 256 octets, ce qui ne permet pas de véhiculer les valeurs de vos 78 variables. On peut augmenter cette largeur de tuyau avec l'option LRECL (Logical RECord Length) dans l'instruction FILE.
... FILE sortie LRECL = 4000 ; ...Le reste de votre programme, lui, n'a pas à changer.
ODS HTML FILE = "chemin et nom de votre fichier.xls" ; TITLE ; FOOTNOTE ; PROC PRINT DATA = votre_table LABEL NOOBS ; RUN ; ODS HTML CLOSE ;Vous obtiendrez ainsi une pseudo feuille Excel (en fait, c'est une page Web habillée d'une extension XLS, mais Excel 97 n'y verra que du feu). En revanche, pour pouvoir ajouter d'autres feuilles au classeur par la suite, il est recommandé d'ouvrir Excel, d'ouvrir la feuille créée et de la sauvegarder en forçant son type à "Classeur Excel". Plus proprement, mais uniquement si vous possédez le module ACCESS TO PC FILES, vous pouvez exporter directement dans une vraie feuille Excel ainsi :
PROC EXPORT DATA = votre_table OUTFILE = "chemin et nom de votre fichier.xls" REPLACE DBMS = EXCEL97 ; RUN ;Pour savoir si vous possédez ledit module, exécutez le programme suivant :
PROC SETINIT NOALIAS ; RUN ;et regardez dans la Log. Si une ligne "SAS/ACCESS Interface to PC Files" y apparaît (ou un intitulé approchant, il varie selon les versions), c'est bon. Sinon, il faudra opter pour la première solution.
ods rtf body = "c:\temp\essai.doc" ; proc print data = grosse.table ; run ; ods rtf close ; options noxwait ; x "start winword" ; DATA _null_ ; BIDON = sleep(10) ; /* attente de l'ouverture de Word */ RUN ; filename word DDE "winword|system" ; DATA _null_ ; FILE word ; PUT '[FileOpen .name="C:\temp\essai.doc"]' ; /* ouverture du document Word */ PUT '[FileSaveAs .Name="essai.htm" .Format=wdFormatHTML]' ; /* enregistrement au format HTML */ PUT '[FileExit 1]' ; /* fermeture de Word */ RUN ;
- remplacer tous les points du tableau par des virgules sous Excel (avec un Remplacer)
- changer le séparateur décimal (Menu Démarrer de Windows, Panneau de Configuration, Paramètres Régionaux, onglet Nombres) de la virgule pour le point.
- si le tableau est généré par une PROC TABULATE, rajouter à l'instruction TABLE qu'il faut employer des formats NUMXx.y, qui fonctionnent comme les formats numériques x.y habituels, mais affichent une virgule comme séparateur décimal ! Pour cela, la commande à insérer est *format=NUMX12.2 par exemple.
- si le tableau est généré par une PROC PRINT, une PROC TABULATE ou une PROC REPORT, utiliser les instructions de formatage avec l'attribut de style TAGATTR qui permet d'envoyer à Excel des indications de format de cellule (cf. L'export de SAS vers Excel expliqué à ma fille)
Bonjour,
je travaille sur serveur et souhaiterais enregistrer mes tables sur le serveur sous un autre format que le format SAS (pour importation sous BO designer par la suite). Merci d'avance.
Bonjour.
Pour l'export vers Business Objects, le type de fichier le plus simple à transmettre depuis SAS est un fichier texte à séparateur tabulation. On peut le produire, avec une version 8 ou supérieure, à l'aide de la procédure EXPORT, comme le titre de votre question le suggérait :
PROC EXPORT DATA = sashelp.class OUTFILE = "~/test.dat" DBMS = TAB ; RUN ;
Le répertoire ~ est la racine de votre compte utilisateur.
L'autre option est d'utiliser un peu de macro-langage et au final une étape Data pour réaliser cet export. Le macro-langage récupère auprès du dictionnaire des données (créé par la PROC CONTENTS) une liste de noms de variable pour l'en-tête du fichier, et une liste de noms de variables pour l'export proprement dit. Ces créations de macro-variables se font dans une procédure SQL. Enfin, une étape Data d'export "classique" avec instructions SET, FILE et PUT, permet d'écrire dans le fichier voulu.
PROC CONTENTS DATA = sashelp.class OUT = work.dico NOPRINT ; RUN ; PROC SQL NOPRINT ; SELECT QUOTE(LEFT(TRIM(name))), LEFT(TRIM(name)) INTO : liste_en_tete SEPARATED BY " '09'x ", liste_variables SEPARATED BY " '09'x " FROM work.dico ORDER BY varnum ; QUIT ; DATA _NULL_ ; SET sashelp.class ; FILE "c:\test.dat" ; IF _N_ = 1 THEN PUT &liste_en_tete ; PUT &liste_variables ; RUN ;
Le charme de ces deux programmes est qu'ils ne nécessitent jamais l'énumération des noms des variables (pratique quand on possède des dizaines ou des centaines de colonnes dans la table à exporter).
Formats
- attention à ne pas confondre LENGTH et FORMAT ; le premier est le nombre d'octets sur lequel une valeur est stockée et le second une indication de la manière dont les valeurs sont affichées. Dans le cas d'une variable caractère, les deux sont souvent semblables : une variable stockée sur 3 octets s'affiche sur 3 caractères (LENGTH=$ 3 et FORMAT=$3.). Pour les variables numériques, on a un LENGTH de 8 (par défaut) et un affichage assez libre : BEST12. signifie juste que SAS utilisera au plus 12 caractères pour afficher la valeur. Le LENGTH de 8 est approprié si la variable contient des décimales. Sinon, selon son ordre de grandeur, on peut gagner de la place avec un LENGTH plus court, entre 3 et 7.
- la compression n'est pas un moyen de gagner du TEMPS mais de la PLACE. Je n'ai pas l'impression que ce soit votre but ; en effet, une table compressée (zippée en interne par SAS) nécessite plus de temps à s'ouvrir (il faut la décompresser) et à s'écrire (il faut la recompresser). Ce n'est donc pas forcément la solution espérée.
data format.fmtDRCourt; set tdbprod.BaseCourtiers (keep=gc DR rename=(gc=start dr=label)); by start; type="N"; /* N Numérique */ fmtname="DRCOURT"; run; proc format lib=format cntlin = format.fmtDRCourt /*fmtlib*/; run;
Je vous propose la variante suivante. DATA format.fmtDRCourt ; SET tdbprod.BaseCourtiers (KEEP = gc dr RENAME=(gc=start)) ; BY start ; LENGTH label $32 ; type="N" ; /* N Numérique */ fmtname="DRCOURT" ; IF _N_=1 THEN DO ; hlo = "O" ; /* ligne OTHER */ label = "Autres" ; OUTPUT ; END ; hlo = " " ; label = dr ; /* ou PUT(dr, format.) si DR est une variable numérique */ OUTPUT ; RUN ; PROC FORMAT LIB=format CNTLIN = format.fmtDRCourt FMTLIB ; RUN ;La variable HLO (High, Low, Other) permet de repérer les lignes "spéciales" dans le descriptif d'un format : celles qui utilisent un de ces trois mots-clés. La variable HLO vaut alors "L", "H" ou "O" selon les cas.
proc format; value anccrea low- mdy(12,31,2002) = "1- avant 01/2003" mdy(12,31,2002)-mdy(12,31,2004)= "2- entre 2003 et 2004 " mdy(12,31,2004)-high= "3- depuis 2005 " other ="???"; run;et ça
proc format; value anccrea low- '31/12/2002'd = "1- avant 01/2003" ...Merci. La 2e solution n'était pas bien loin du compte. Simplement, la forme de la date entre guillemets doit être JJ puis mois sur 3 lettres en anglais puis année. Comme dans un WHERE.
PROC FORMAT ; VALUE anccrea LOW- '31dec2002'd = "1- avant 01/2003" ... ; RUN ;
proc format; value $test '10' = 'l'arbre'; run;Comment faire comprendre à SAS qu'il ne s'agit pas de la fin du label ? Merci Bonjour. Le plus simple pour résoudre votre problème est tout simplement d'écrire votre libellé entre guillemets doubles. Il n'y aura alors pas de confusion avec les apostrophes. Dans SAS, les guillemets doubles et les apostrophes sont totalement équivalents, à condition qu'ils soient par paires identiques (= quand on ouvre des guillemets doubles, on ferme des guillemets doubles). La seule différence tient à un texte contenant une référence à une macro-variable &nomMV. Entre guillemets simples (apostrophes), la macro-variable ne sera pas résolue ; entre guillemets double, elle le sera.
proc format; value $test '10' = "l'arbre"; run;
PROC TABULATE DATA = ... FORMAT = NUMX12.2 ;devrait faire l'affaire.
OPTION LOCALE = FRENCH ;par exemple en début de programme SAS, en dehors de toute procédure et étape Data.
proc format; value pop (multilabel) low-35="35 ans et moins" low-high/* ?? */="tout le monde"; run;mais si j'applique ce format dans une proc freq par exemple:
proc freq data=****; table age; format age pop.; run;j'obtiens bien les 35 ans et moins d'une part, mais dans "tout le monde" je n'ai que les plus de 35 ans. Comment obtenir l'ensemble de la population? Merci pour votre réponse Bonjour. Il n'est malheureusement pas possible d'utiliser les formats MULTILABEL partout. Seules les procédures MEANS et TABULATE les supportent. Une alternative pour votre problème : dupliquer les observations correspondant aux moins de 35 ans, avec une étape Data.
DATA work.pour_etude ; SET *** ; IF age < 35 THEN DO ; doublon = 1 ; OUTPUT ; END ; doublon = 0 ; /* pour tout le monde */ OUTPUT ; RUN ;Ensuite il suffit d'habiller la variable DOUBLON avec un format : 0 -> tout le monde 1 -> moins de 35 ans.
PROC FORMAT ; PICTURE milliers (ROUND) 0 - HIGH = "000 000 009" ; RUN ;Vous utilisez ensuite le format milliers. quand vous en avez besoin. Pour plus d'informations sur les formats "picture", voir Les pictures expliqués à ma fille.
filename sortie DDE "excel|Feuil1!l1c2:l1c79" notab; DATA _null_; SET pgm; FILE sortie; PUT COL1 '09'x COL2 '09'x COL3 '09'x COL4 '09'x COL5 '09'x COL6 '09'x COL7 '09'x COL8 '09'x COL9 '09'x COL10 '09'x COL11 '09'x COL12 '09'x COL13 '09'x COL14 '09'x COL15 '09'x COL16 '09'x COL17 '09'x COL18 '09'x COL19 '09'x COL20 '09'x COL21 '09'x COL22 '09'x COL23 '09'x COL24 '09'x COL25 '09'x COL26 '09'x COL27 '09'x COL28 '09'x COL29 '09'x COL30 '09'x COL31 '09'x COL32 '09'x COL33 '09'x COL34 '09'x COL35 '09'x COL36 '09'x COL37 '09'x COL38 '09'x COL39 '09'x COL40 '09'x COL41 '09'x COL42 '09'x COL43 '09'x COL44 '09'x COL45 '09'x COL46 '09'x COL47 '09'x COL48 '09'x COL49 '09'x COL50 '09'x COL51 '09'x COL52 '09'x COL53 '09'x COL54 '09'x COL55 '09'x COL56 '09'x COL57 '09'x COL58 '09'x COL59 '09'x COL60 '09'x COL61 '09'x COL62 '09'x COL63 '09'x COL64 '09'x COL65 '09'x COL66 '09'x COL67 '09'x COL68 '09'x COL69 '09'x COL70 '09'x COL71 '09'x COL72 '09'x COL73 '09'x COL74 '09'x COL75 '09'x COL76 '09'x COL77 '09'x COL78 '09'x; RUN;Or, sur ma feuille Excel, seules les 22 premières variables sont inscrites. Si je diminue le format de mes variables au minimum (format 3.2), j’arrive à obtenir les 64 premières variables. Mais j’ai toujours une perte d’informations… Comment puis-je faire ? Le problème vient de la largeur du "tuyau" utilisé par SAS pour envoyer les infos à Excel ; par défaut, il ne fait que 256 octets, ce qui ne permet pas de véhiculer les valeurs de vos 78 variables. On peut augmenter cette largeur de tuyau avec l'option LRECL (Logical RECord Length) dans l'instruction FILE.
... FILE sortie LRECL = 4000 ; ...Le reste de votre programme, lui, n'a pas à changer.
- remplacer tous les points du tableau par des virgules sous Excel (avec un Remplacer)
- changer le séparateur décimal (Menu Démarrer de Windows, Panneau de Configuration, Paramètres Régionaux, onglet Nombres) de la virgule pour le point.
- si le tableau est généré par une PROC TABULATE, rajouter à l'instruction TABLE qu'il faut employer des formats NUMXx.y, qui fonctionnent comme les formats numériques x.y habituels, mais affichent une virgule comme séparateur décimal ! Pour cela, la commande à insérer est *format=NUMX12.2 par exemple.
- si le tableau est généré par une PROC PRINT, une PROC TABULATE ou une PROC REPORT, utiliser les instructions de formatage avec l'attribut de style TAGATTR qui permet d'envoyer à Excel des indications de format de cellule (cf. L'export de SAS vers Excel expliqué à ma fille)
Je voudrais faire une régression logistique en utilisant des classes de mes variables quantitatives... Pour cela je peux utiliser le noeud transform variables et calculer des classes selon les quartiles ou quelque chose du genre mais le problème c'est que j'aimerais faire une classe exclusivement = 0 ... car pour les montants par exemple il y en beaucoup qui sont égaux à zéro. Donc je voudrais avoir ma 1ère classe seulement pour des valeurs nulles puis la 2ème par exemple pour des valeurs comprises entre zéro exclus et 12000 F... Comment m'y prendre ?
Pour le problème de découpage en classes : voici une solution à la main, parce qu'on ne peut pas faire mieux sans passer par un macro-programme dans le noeud SAS Code pour le faire automatiquement :
- calculer les valeurs des quantiles. Les noter sur un bout de papier (c'est VRAIMENT une solution à la main !)
- dans Transform Variables, créer une nouvelle variable, dont la définition sera : 1+(VAR>0)+(VAR>12000)+(VAR>20000) par exemple. Remplacer VAR par le nom de la variable quali de départ, et 12000 et 20000 par les quantiles de la feuille de papier.
Les tests entre parenthèses renvoient des booléens : 0 pour faux, 1 pour vrai. SEM produit une variable qui vaut : 1 pour les valeurs nulles, 2 pour les valeurs entre 0 exclus et 12000 inclus, 3 pour les valeurs entre 12000 exclus et 20000 inclus, 4 pour les valeurs > 20000.
Bonjour, je dispose d'une table avec des dates sous un certain format. je voudrais savoir comment les afficher via une proc freq sans format, c'est-à-dire en les visualisant sous la forme du nombre de jour depuis le 1er JAN 1960. L'objectif étant de récupérer les dates distinctes de ma table dans une liste, et de boucler dessus. Par avance, merci.
Bonjour.
Pour répondre directement à votre question, ajoutez une instruction FORMAT maVariableDate 6. ; à votre procédure FREQ. Sinon, vous pouvez directement créer une table de dates distinctes avec une procédure SORT avec l'option NODUPKEY, sans avoir besoin de la proc FREQ.
Bonjour. J'ai une date de format $10. (style 10/10/2010) que je voudrais transformer en date DDMMYY10. Merci d'avance de votre réponse.
Bonjour.
Il faudra créer une nouvelle variable, de type numérique ; pour cela, en SQL ou dans une étape Data, la formule sera INPUT(variableExistante, DDMMYY10.) et le résultat sera en nombre de jours depuis le 01/01/1960. Restera ensuite à l'habiller du format date de votre choix.
Bonjour,
j'ai une variable date dans un fichier, et je souhaite faire la répartition en fonction de tranche gérées par un format que je crée... et je n'arrive pas à créer ce format (sans passer par le calcul du nombre de jours correspondants à ma date..)
j'ai essayé ça :
proc format; value anccrea low- mdy(12,31,2002) = "1- avant 01/2003" mdy(12,31,2002)-mdy(12,31,2004)= "2- entre 2003 et 2004 " mdy(12,31,2004)-high= "3- depuis 2005 " other ="???"; run;et ça
proc format; value anccrea low- '31/12/2002'd = "1- avant 01/2003" ...
Merci.
La 2e solution n'était pas bien loin du compte. Simplement, la forme de la date entre guillemets doit être JJ puis mois sur 3 lettres en anglais puis année. Comme dans un WHERE.
PROC FORMAT ; VALUE anccrea LOW- '31dec2002'd = "1- avant 01/2003" ... ; RUN ;
Bonjour.
J'aurais souhaité afficher une date sous la forme suivante : Janvier 2005 (en français, mais sans le numéro du jour).
D'avance merci.
Bonjour.
Si vos données sont sous forme de dates SAS, vous pouvez utiliser :
- les formats "français" de dates de SAS, comme FRADFWDX. qui afficherait 01 janvier 2005 ;
- un format de type particulier, appelé PICTURE, créé par la procédure FORMAT. Dans le cas de votre demande, c'est ce qu'il convient d'utiliser :
PROC FORMAT ; PICTURE testDate LOW - HIGH = '%B %Y' (DATATYPE = DATE) ; RUN ;
Dans cette syntaxe, l'option DATATYPE = DATE permet de spécifier le type de données lues. On peut également avoir deux autres valeurs, TIME et DATETIME.
Les éléments %Y, %B qui composent la valeur affichée sont des mots-clés reconnus de la procédure FORMAT. Les principaux éléments sont :
- %a = jour de la semaine en français sur 3 lettres
- %A = jour de la semaine en français
- %b = mois sur 3 lettres en français
- %B = mois en français
- %d = jour du mois sans zéro initial
- %0d = jour du mois sur deux chiffres
- %j = jour de l'année (de 1 à 366)
- %m = mois (1 à 12) sans zéro initial
- %0m = mois sur deux chiffres
- %0y = année sur deux chiffres
- %Y = année sur quatre chiffres
Enfin, il est recommandé d'employer des apostrophes et non des guillemets autour de la valeur formatée afin d'éviter toute intervention du compilateur macro.
Bonjour.
Dans une table SAS que j'ai récupérée, j'ai une variable qui contient manifestement une date, qui semble numérique sur une longueur de 8, mais elle a un aspect bizarre. Une valeur, par exemple, est : 14JUN1977:00:00:00. Les fonctions dates habituelles (YEAR, INTNX, etc.) me renvoient des résultats aberrants quand je les applique à cette variable. Que faire ?
D'avance merci.
Vous êtes en présence d'une variable de "type" Datetime (stockée en nombre de secondes depuis le 01/01/1960 à minuit). C'est donc bien du numérique sur 8 octets (8 octets ça permet de stocker des entiers énormes). Mais ce n'est pas une DATE au sens où les fonctions comme YEAR s'y attendent, c'est à dire un nombre de jours depuis le 01/01/1960. Quant à son aspect "bizarre", il s'explique par un format DATETIME. spécialement conçu pour ce type d'information.
La fonction DATEPART permet d'extraire la partie "date" d'un Datetime. Mais il faut bien penser à affecter un format date (DDMMYY10. par exemple) à la variable ainsi créée.
Une étape Data comme celle-ci résoud le problème :
DATA ma_nouvelle_table ; SET mon_ancienne_table ; variable_date = DATEPART(variable_datetime) ; FORMAT variable_date DDMMYY10. ; RUN ;
(Il convient bien sûr de changer les noms des tables et des variables pour coller à votre sujet.)
Je travaille en client/serveur. Je crée en RSUBMIT des formats avec une PROC FORMAT. Je fais une option FMTSEARCH sur la librairie qui contient le catalogue de formats. Pour l'exécution de procédures, tout va bien. Mais quand je veux regarder ma table avec l'Explorer, SAS me dit qu'il ne trouve pas les formats. Que se passe-t-il ?
LE PROBLEME : l'architecture client/serveur ne fait pas transiter les formats. Cela implique entre autres qu'on ne peut pas utiliser sur le client les formats du serveur et vice-versa, et que l'on ne peut pas créer sur le serveur des formats depuis le poste client (même dans un RSUBMIT).
LA SOLUTION : Première étape, créer le(s) format(s) en LOCAL. Donc sur le PC. Pour cela, exécuter EN-DEHORS du bloc RSUBMIT / ENDRSUBMIT la procédure formats avec une syntaxe
PROC FORMAT LIB = librairie_locale ; etc... RUN ;
Deuxième étape, le catalogue FORMATS créé dans la librairie locale doit être "remonté" sur le serveur. Pour cela, SUR LE SERVEUR cette fois (dans un bloc RSUBMIT / ENDRSUBMIT), utiliser la PROC UPLOAD qui est dédiée à la copie de "membres" SAS d'une librairie client dans une librairie distante du serveur. Si, par exemple, vous avez stocké les formats dans WORK.FORMATS, vous les remonterez ainsi vers ServLib.FORMATS :
PROC UPLOAD INCAT = WORK.FORMATS OUTCAT = ServLib.FORMATS ; RUN ;
Graphiques
PLOT varY * varX = varGroupe ;permet d'obtenir plusieurs séries de points correspondant à différents groupes d'observations.
SYMBOL i = rl v = dot ; PROC GPLOT DATA = sashelp.class ; PLOT weight * height = sex ; RUN ; QUIT ;
axis1 value=(h=1.5) label=(h=1.5 "^S={font_face=symbol}m ^S={}") offset=(1.5,1.5) length=100 pct;
axis2 value=(h=1.5).......Mais cela ne fonctionne pas, SAS n'interprète pas la police Symbol. Auriez-vous une solution? Merci Les ESCAPECHAR comme vous avez essayé ne fonctionnent que pour les titres gérés par l'ODS. Les axes sont gérés par SAS/GRAPH pour les procédures GPLOT, GCHART ou BOXPLOT. Il vaudrait mieux utiliser la police GREEK fournie par SAS via une option FONT dans la définition du label.
AXIS1 value=(h=1.5) label=(h=1.5 font=GREEK "m" font=swiss "g") offset=(1.5,1.5) length=100 pct;
DATA work.deux ; SET table1 (IN=annee1) table2 (IN=annee2) ; IF annee1 THEN annee = 2005 ; IF annee2 THEN annee = 2006 ; RUN ; PROC GCHART DATA=work.deux ; VBAR variable / SUBGROUP=annee ; RUN ; QUIT ;Globalement, l'idée lors de la fusion des deux tables est de garder une trace de leur origine (avec des IN). On peut choisir d'empiler (SET) ou de joindre (MERGE) les deux tables ; il est plus simple pour l'empilement (options GROUP, SUBGROUP, BY) d'avoir plusieurs séries d'observations, donc un empilement préalable.
STARTPAGE = NOLes sorties de vos procédures (graphiques ou tableaux) se trouveront à la suite les unes des autres, sans sauts de pages.
DATA work.shoes ; SET sashelp.shoes (WHERE = (region IN: ("Africa","Canada","Western"))) ; SELECT (region) ; WHEN ("Canada") ordre = 1 ; WHEN ("Africa") ordre = 2 ; OTHERWISE ordre = 3 ; END ; RUN ; PROC SORT DATA = work.shoes ; BY ordre ; RUN ; PROC BOXPLOT DATA = work.shoes ; PLOT sales * region ; RUN ;
PROC GCHART DATA = sashelp.class ; VBAR sex / SUMVAR = age TYPE = MEAN DES = "Moyenne d'âge par sexe" ; RUN ; QUIT ;
ODS RTF FILE = "..." STARTPAGE = NEVER ; PROC Gxxx ... ; ... RUN ; QUIT ; ODS RTF CLOSE ;
Plateforme / OS | Instruction |
Windows | GOPTION KEYMAP = winansi ; |
Unix / Linux | GOPTION KEYMAP = sas8859 ; |
GOPTIONS HSIZE = 10cm VSIZE = 15cm ; PROC G... ; etc...On peut aussi spécifier les tailles en pouces ("in" après le nombre) ou en points ("pt").
PROC GPLOT DATA = ... ; PLOT y1*x1 y2*x2 ; RUN ; QUIT ;L'option OVERLAY permet de superposer les graphiques... Attention, par défaut, pas de légende (d'où l'astuce de désigner LEGEND1 qui n'existe pas, mais il va se débrouiller). Attention aussi aux axes qui seront ceux des premières variables citées (x1 et y1 ici).
PROC GPLOT DATA = ... ; PLOT y1*x1 y2*x2 / OVERLAY LEGEND = legend1 ; RUN ; QUIT ;
PROC PLOT DATA = tableSAS ; PLOT varY * varX = "#" $ variableTexte ; RUN ; QUIT ;Le signe # sert de marqueur aux points (il peut être remplacé par ce que l'on veut) et variableTexte contient les noms de modalités, identifiants d'individus, etc. A noter qu'à partir de la version 9.1 de SAS, ODS GRAPHICS produit le 1er plan factoriel d'une AFC avec la procédure CORRESP. En revanche, il nécessitera SAS/GRAPH en version 9.2 (et redevient dans SAS/Base à partir de SA 9.3 !!!).
Importation
LIBNAME fichier6 V6 '/user/chemin/rep' ; LIBNAME fichier8 '/user/chemin/rep' ; PROC COPY IN = fichier6 OUT = fichier8 ; RUN ;Autre possibilité, vous pouvez télécharger gratuitement depuis Internet le SAS Viewer (il est aussi sur les CD d'installation, demandez aux informaticiens) qui devrait permettre d'ouvrir la table Unix et de l'enregistrer sous... soit directement le format SAS7BDAT Windows v8 - v9, soit au pire en fichier plat .CSV et vous devrez refaire un import puis remettre les labels.
%macro essai; data table; input variable; cards; 1 2 3 ; run; %mend essai; %essai; ERROR: The macro ESSAI generated CARDS (data lines) for the DATA step, which could cause incorrect results. The DATA step and the macro will stop executing. NOTE: The data set WORK.TABLE has 0 observations and 1 variables.Bonjour. Effectivement, l'emploi de CARDS, CARDS4 et DATALINES est interdit dans un macro-programme. La raison est sans doute la difficulté prévisible de bien repérer les données proposées. Une alternative sera de mettre les données dans un fichier texte et de le lire avec INFILE ... INPUT.
data _null_; infile "c:\essai.txt" firstobs=2 dlm =','; input a$ b$; run;Bonjour. CALL SYMPUT ne s'applique pas forcément à des tables SAS en dur ; tout ce qui peut être chargé dans le vecteur de travai (PDV) peut être utilisé dans un CALL SYMPUT pour alimenter des macro-variables.
data _null_; infile "c:\essai.txt" firstobs=2 dlm =','; input a$ b$; call symput ("mva",a) ; call symput ("mvb",b) ; run;Ce programme doit fonctionner correctement et vous créer les MV nécessaires.
dateSAS = DATEPART(dateSPSS + "15oct1582:00:00:00"dt) - 1 ; FORMAT dateSAS DDMMYY10. ;
LIBNAME maBase ORACLE USER="..." PASSWORD="..." PATH="..." ;ou bien
PROC SQL ; CONNECT TO ORACLE (USER="..." PASSWORD="..." PATH="...") ; SELECT * FROM CONNECTION TO ORACLE (requête Oracle) ; DISCONNECT FROM ORACLE ; QUIT ;Dans le premier cas, on accède aux données Oracle comme si c'était des tables SAS ; dans le second, on peut ajouter un CREATE TABLE dans la proc SQL pour récupérer en table SAS les données extraites par la requête.
La démarche suivante pose problème :
- j'ai créé un échantillon sur ma session Unix...
- je l'ai transféré en tant que fichier à plat sur Windows NT
- je l'ai importé sous SEM...
le problème qui se pose : des variables qui étaient dans ma base de départ de type char deviennent de type num... j'ai voulu les modifier dans un noeud IDS mais ça ne fonctionne pas... Y a t-il un autre moyen?
Il s'agit en fait d'un problème d'importation de SAS lui-même, pas spécifique à SEM. Il prend comme numériques toutes les variables n'ayant que des valeurs chiffrées (même s'il s'agit de codes). Le plus simple est peut-être de faire l'import à la main avec une étape Data et une instruction INPUT.
Macro
data ww.CMb; set ww.CM1b ww.CM2b ... ww.CM40b; run;Merci Bonjour, et merci de votre question. Vous pouvez utiliser un programme comme celui-ci :
%MACRO empilement (nbTables) ; DATA ww.CMb ; SET %DO i=1 %TO &nbTables ; ww.CM&i.b %END ; ; RUN ; %MEND empilement ;
%empilement (40)A partir de SAS 9.2, plus besoin de macros ! Vous pouvez écrire directement
SET ww.CM1-ww.CM40 ;dans votre étape Data. Par contre, comme dans votre cas le nom des tables ne se termine pas par un nombre, il faudra rester à la solution macro.
%macro essai(a=); data outpct; set outpct; variable='&a';/*???*/ run; %mend essai;
%essai(a=sonf);Je voudrais en fait que dans ma table outpct apparaisse une variable nommée "variable" dont la modalité serait ici 'sonf'. Comment faire ? Merci d'avance. Il suffit de mettre des doubles guillemets : "&a" , au lieu des simples. Ces derniers bloquent l'action du compilateur macro.
proc tabulate data=data.tab3 missing ; class cat ; class sonf; tables sonf all='Total',cat*(n*f=10.0 pctn='%'*f=10.1) all='Total'*(n*f=10.0 pctn='%'*f=10.1) ; run ;où chaque variable (comme ici "sonf") est traitée en fonction de la variable "cat". Je voudrais à chaque fois récupérer le risque relatif (proc freq option cmh) et sous chaque tableau écrire : "Le risque relatif est : ....". Comment faire? Merci d'avance. voici un exemple de réponse :
- avec une proc Freq (et l'option RELRISK plutôt que CMH plus bavarde), calculer les risques relatifs. Ceux-ci sont édités dans un objet ODS appelé RelativeRisks (si vous utilisez CMH, l'objet se nomme CommonRelRisks)
- ajouter, juste au-dessus de la proc Freq, une instruction ODS OUTPUT pour récupérer ces informations dans une table SAS
- après la proc Freq, ajouter une étape Data pour générer une macro-variable contenant la valeur du risque relatif qui vous intéresse
- se servir de la valeur de cette macro-variable dans un FOOTNOTE ou un ODS TEXT.
ODS EXCLUDE ALL ; ODS OUTPUT relativeRisks = work.rr ; PROC FREQ DATA = cours.produits ; TABLE couleur * primeur / RELRISK ; RUN ; ODS SELECT ALL ; DATA _NULL_ ; SET work.rr (WHERE = (studyType = "Case-Control (Odds Ratio)")) ; CALL SYMPUT ("rr", LEFT(PUT(value, 12.2))) ; RUN ; ODS RTF FILE = "c:\temp\essai.doc" STARTPAGE = NEVER ; PROC TABULATE DATA = cours.produits ; CLASS couleur primeur ; TABLE (couleur ALL="TOTAL") , (primeur ALL="TOTAL") * (N * F = 7. colPctN = "%" * F = 7.1) ; RUN ; ODS RTF TEXT = "Le risque relatif est : &rr" ; ODS RTF CLOSE ;Par rapport au programme de votre question, je préfère l'emploi des mots-clés PCTN, COLPCTN et ROWPCTN à celui des spécifications entre < et > du dénominateur de ces pourcentages ; PCTN sont des pourcentages de l'ensemble du tableau, COLPCTN des pourcentages-colonnes et ROWPCTN des pourcentages-lignes.
%let liste1= a b c ; %let liste2=(a f d) ; %let liste3=;Je souhaite comparer chaque variable de la liste1 avec toutes les variables de la liste2 pour constituer une liste3 excluant de la liste1 les variables figurant dans la liste2 (soit liste3=b c); Ci après le code que j’ai écris
%do i=1 %to &n; %if %scan(&liste1,&i) not in &liste2 %then %do; %let liste3=liste3 %scan(&liste1,&i); %end; %end;NB : n est le nombre d’éléments de la liste1 que j’ai précédemment récupéré. Le pb c’est que ça ne marche pas et ci-après la log : ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was: %scan(&liste1,&i) not in &liste2 Je ne comprends pas cette erreur. Merci d'avance de votre aide. Bonjour. Le problème, c'est qu'avant la version 9 de SAS, l'opérateur IN n'existe pas en macro-langage. Il le prend donc pour du texte et n'arrive pas à évaluer la condition. Par contre, on peut utiliser une fonction comme TRANWRD, qui va remplacer un nom de variable vu dans LISTE2 par un blanc. Après avoir passé tout LISTE2 en revue (TRANWRD n'accepte qu'un mot à la fois à remplacer), on supprime les blancs inutiles pour la beauté du résultat.
%let liste1= a b c ; %let liste2= a f d ; %let liste3=; %MACRO sansListe2 ; %GLOBAL liste3 ; %LET liste3 = &liste1 ; %LET i = 1 ; %DO %WHILE (%SCAN(&liste2,&i) NE ) ; %LET liste1 = %SYSFUNC(TRANWRD(&liste1,%SCAN(&liste2,&i), )) ; %LET i = %EVAL(&i + 1) ; %END ; %LET liste3 = %SYSFUNC(COMPBL(&liste3)) ; %MEND sansListe2 ; %sansListe2 ;
DATA maTable ; SET maTable (RENAME = (v3-v15 = x20-x32)) ; RUN ;Les variables s'appellent à l'origine v3, v4, v5, ..., v15 et après renommage, x20, x21, ..., x32. Sinon, vous pouvez construire une table SAS avec les anciens et les nouveaux noms (éventuellement à partir d'une feuille Excel importée). L'exemple ci-dessous vous montre comment on peut ensuite générer automatiquement la litanie de RENAME.
DATA work.nouveaux_noms ; INPUT ancien $ nouveau $ ; DATALINES ; name nom sex sexe weight poids height taille ; RUN ; %LET table = sashelp.class ; /* NE PLUS RIEN MODIFIER APRES CETTE LIGNE */ DATA _NULL_ ; SET work.nouveaux_noms END = fin ; IF _N_=1 THEN DO ; CALL EXECUTE ("DATA work.nouvelle_table ;") ; CALL EXECUTE ("SET &table (RENAME=(") ; END ; CALL EXECUTE (ancien!!"="!!nouveau) ; IF fin THEN DO ; CALL EXECUTE (")) ;") ; CALL EXECUTE ("RUN ;") ; END ; RUN ;
- Déclarer une bibliothèque sur ce répertoire. LIBNAME ma_macro "c:\temp" ;
- Déclarer à SAS qu'on veut y mettre des macros (ou qu'il y en a déjà là). OPTIONS MSTORED SASMSTORE = ma_macro ;
- Exécuter le macro-programme en modifiant sa PREMIERE ligne : %MACRO mon_macro_programme (parametre1, parametre2, ...) / STORE ; ... %MEND mon_macro_programme ;
%mon_macro_programme (valeur1, valeur2, ...) ;
%IF %SYSEVAL(&seuil.-&ecarty.) > 0 %THEN ...et obtenir un résultat correct !
proc transpose data=infic prefix=cnt out=outfic; var nocnt; by client; run ;va générer cnt1 à cntn. Comment récupérer le nombre de variables générées (n) dans une étape data ? Merci. Pour mettre ce nombre dans une macro-variable, voici un premier programme :
DATA _NULL_ ; SET outfic ; ARRAY transpose cnt: ; CALL SYMPUT ("nbNllesVar", DIM(transpose)) ; STOP ; RUN ;Vous récupérez le nombre de variables créées par la procédure TRANSPOSE dans la macro-variable &nbNllesVar. Pour disposer de ce nombre sous forme de variable dans l'étape Data, il suffit de modifier légèrement ce programme :
DATA ... ; SET outfic ; ARRAY transpose cnt: ; nbVar = DIM(transpose) ; /* il est également possible d'opérer des traitements avec une boucle sur l'Array : DO i = 1 TO DIM(transpose) ; traitement sur transpose(i) END ; */ RUN ;
%LET recherche = ar ; PROC PRINT DATA = sashelp.class ; WHERE soc LIKE "%&recherche%" ; RUN ;Comment résoudre ce problème ? Il faut masquer au macro-compilateur les deux %. Pour cela, on utilisera la macro-fonction %NRQUOTE, qui masque des caractères pendant la phase de résolution (transformation du programme par le macro-compilateur)... Le macro-compilateur n'est donc intéressé que par l'expression &recherche, qui ne pose pas de problème. Il est ensuite transmis le programme correct au compilateur SAS, qui aura le droit de voir les %.
%LET recherche = ar ; PROC PRINT DATA = sashelp.class ; WHERE soc LIKE "%NRQUOTE(%)&recherche%NRQUOTE(%)" ; RUN ;
LIBNAME bib1 "..." ; LIBNAME bib2 "..." ; LIBNAME bibmac (bib1 bib2) ; option SASMSTORE = bibmac MSTORED ;SAS ira d'abord chercher dans le catalogue bib1.sasmacr, puis en cas d'échec (le macro-programme demandé ne s'y trouve pas) dans bib2.sasmacr. L'écriture d'une nouvelle macro se fera dans bib1.sasmacr. Bien sûr, cela marche avec plus de deux bibliothèques.
%if &Nberr=0 %then %do; « arrêter tout » %end ;Si c'est possible comment faire ? Avec les versions de SAS antérieures à la 9, on ne peut traiter le problème qu'à "l'ancienne" avec un %GOTO vers un autre point du programme (après lequel on ne fera plus rien).
%macro MP1 ; %if condition %then %do; %goto exit; %end;
%exit: %mend MP1;Avec la version 9 apparaissent deux instructions %ABORT et %RETURN qui permettent d'arrêter l'exécution du macro-programme. %ABORT arrête le MP avec un message d'erreur tandis que %RETURN arrête le MP sans erreur.
%let i = %eval (&i + 1) ;
%macro essai; data table; input variable; cards; 1 2 3 ; run; %mend essai; %essai; ERROR: The macro ESSAI generated CARDS (data lines) for the DATA step, which could cause incorrect results. The DATA step and the macro will stop executing. NOTE: The data set WORK.TABLE has 0 observations and 1 variables.Bonjour. Effectivement, l'emploi de CARDS, CARDS4 et DATALINES est interdit dans un macro-programme. La raison est sans doute la difficulté prévisible de bien repérer les données proposées. Une alternative sera de mettre les données dans un fichier texte et de le lire avec INFILE ... INPUT.
data _null_; infile "c:\essai.txt" firstobs=2 dlm =','; input a$ b$; run;Bonjour. CALL SYMPUT ne s'applique pas forcément à des tables SAS en dur ; tout ce qui peut être chargé dans le vecteur de travai (PDV) peut être utilisé dans un CALL SYMPUT pour alimenter des macro-variables.
data _null_; infile "c:\essai.txt" firstobs=2 dlm =','; input a$ b$; call symput ("mva",a) ; call symput ("mvb",b) ; run;Ce programme doit fonctionner correctement et vous créer les MV nécessaires.
ODS HTML FILE = "chemin et nom de votre fichier.xls" ; TITLE ; FOOTNOTE ; PROC PRINT DATA = votre_table LABEL NOOBS ; RUN ; ODS HTML CLOSE ;Vous obtiendrez ainsi une pseudo feuille Excel (en fait, c'est une page Web habillée d'une extension XLS, mais Excel 97 n'y verra que du feu). En revanche, pour pouvoir ajouter d'autres feuilles au classeur par la suite, il est recommandé d'ouvrir Excel, d'ouvrir la feuille créée et de la sauvegarder en forçant son type à "Classeur Excel". Plus proprement, mais uniquement si vous possédez le module ACCESS TO PC FILES, vous pouvez exporter directement dans une vraie feuille Excel ainsi :
PROC EXPORT DATA = votre_table OUTFILE = "chemin et nom de votre fichier.xls" REPLACE DBMS = EXCEL97 ; RUN ;Pour savoir si vous possédez ledit module, exécutez le programme suivant :
PROC SETINIT NOALIAS ; RUN ;et regardez dans la Log. Si une ligne "SAS/ACCESS Interface to PC Files" y apparaît (ou un intitulé approchant, il varie selon les versions), c'est bon. Sinon, il faudra opter pour la première solution.
proc corresp data=stage.basefinale outc=corr; tables Nom_DRD naf cible effectif_consolide2 nb_etablissement2 chiffre_affaire2 libelle_Forme_Juridique_Prospect Departement_prospect ; run;Mes questions sont les suivantes : Est-ce que l'ACM effectué ci-dessus est bonne? Et sur quels résultats exactement dois-je réaliser l'analyse discriminante (inertie, mass, dim,....)? Merci d'avance ! Bonjour. Pour pouvoir enchaîner ACM et analyse discriminante, il faut réaliser l'ACM dans l'espace des individus. Or l'instruction TABLES ne permet de se placer que dans l'espace des variables. Vous devez plutôt utiliser l'instruction VAR, et mettre en entrée une table d'indicatrices (à créer avec la procédure Transreg par exemple). Vous trouverez sur notre site une macro SAS pour faire un modèle DISQUAL.
PROC PLOT DATA = tableSAS ; PLOT varY * varX = "#" $ variableTexte ; RUN ; QUIT ;Le signe # sert de marqueur aux points (il peut être remplacé par ce que l'on veut) et variableTexte contient les noms de modalités, identifiants d'individus, etc. A noter qu'à partir de la version 9.1 de SAS, ODS GRAPHICS produit le 1er plan factoriel d'une AFC avec la procédure CORRESP. En revanche, il nécessitera SAS/GRAPH en version 9.2 (et redevient dans SAS/Base à partir de SA 9.3 !!!).
ODS
PROC FORMAT ; VALUE $prod "TABLE" = "VERY LONG VALUE INSTEAD OF JUST ""TABLE"" " ; RUN ; ODS RTF FILE="c:\temp\sans uniform.doc" ; ODS TAGSETS.RTF FILE="c:\temp\avec uniform.doc" UNIFORM ; PROC REPORT DATA=sashelp.prdsale NOWD ; COLUMNS year month product actual predict ; FORMAT product $prod. ; DEFINE year / DISPLAY ; RBREAK BEFORE / SUMMARIZE ; RUN ; ODS RTF CLOSE ; ODS TAGSETS.RTF CLOSE ;
ODS TRACE ON / LISTING ; PROC xxx ... ; ... RUN ; ODS TRACE OFF ;Les informations sur chaque objet s'ajoutent dans la fenêtre Output. Une fois qu'on connaît le nom (QUANTILES pour celui qui vous concerne), on peut écire :
PROC UNIVARIATE ... ; ... ODS OUTPUT quantiles = work.maTableSAS ; RUN ;ou, pour n'afficher que le tableau de quantiles :
ODS SELECT quantiles ; PROC UNIVARIATE ... ; ... RUN ; ODS SELECT ALL ;
ODS EXCLUDE ALL ; PROC TABULATE DATA = ... OUT = ... ; ... RUN ; ODS SELECT ALL ;
- faire précéder le programme de l'option système VALIDVARNAME=ANY qui va autoriser les caractères accentués dans les noms.
- Faire un RENAME dès que possible pour se débarrasser de l'accent et pouvoir repositionner VALIDVARNAME à sa valeur initiale, V7.
OPTION VALIDVARNAME=ANY ; ODS OUTPUT crossTabFreqs = work.maSortie (RENAME = ("Fréquence"n = Frequence)) ; PROC FREQ DATA = ... ; TABLE ... ; RUN ; OPTION VALIDVARNAME=V7 ;
DEFINE ... / ... STYLE(HEADER)=[URL="adresse"] ;
ODS OUTPUT OddsRatios = nomTableSAS ;Pour fonctionner, il faut que cette instruction soit entre les instructions PROC LOGISTIC et RUN.
ODS EXCLUDE ALL ; /* plus aucune sortie sauf ODS OUTPUT */ PROC TTEST ... ; ... ODS OUTPUT ... ; RUN ; ODS SELECT ALL ; /* retour à la normale */
ODS OUTPUT ANOVA = work.maTable ; PROC REG DATA = ... ; ... RUN ; QUIT ;
ODS OUTPUT parameterEstimates = work.coeffs ;et vous retrouverez dans la table COEFFS de la bibliothèque WORK vos coefficients.
ODS TRACE ON ; PROC xxx ... ; ... RUN ; ODS TRACE OFF ;Dans la fenêtre LOG, chaque morceau des sorties correspond à un cartouche indiquant, entre autres (ligne NAME), le nom de l'objet ODS produit.
ods html body='c:\essai.htm' (title="~~~~~~ Tableau de bord direction financière ~~~~~~"); proc print data=sashelp.class; run; ods html close;
/* partie 1 : modifier le Registry */ data _null_ ; file "c:\temp\regtemp.reg" ; put "[ODS\PREFERENCES\HTML]" / "'AutoNavigate'=int:0" ; run ;
proc registry import = "c:\temp\regtemp.reg" ; run ;
/* étape 2 : le traitement pour lequel on ne veut pas avoir le résultat présenté spontanément */
/* étape 3 : remettre le Registry à sa valeur par défaut */ proc registry uninstall = "c:\temp\regtemp.reg" ; run ;
- on fait précéder de CX les codes RGB sans signe dièse
- on peut aussi utiliser des nuances de gris, de GRAY00 à GRAYFF
... style = { background = CX0000FF }Note : il n'est pas nécessaire d'avoir une licence SAS/GRAPH pour que cela fonctionne.
ODS HTML BODY = ... STYLESHEET = "mon_fic.css" ;Ce fichier .css, qu'on appelle une feuille de style, permet de définir nombre de polices, couleurs, etc... Il peut se mettre en commun à plusieurs pages Web (d'où un gain de place). On peut aussi utiliser un des nombreux styles prédéfinis de SAS.
PROC TEMPLATE ; LIST styles ; RUN ;
- - DBCS
- - DBCSTYPE PCMS
- -SASHELP ( "!SASCFG\SASCFG" "!sasext0\dbcs\sashelp" "!sasroot\core\sashelp" "!sasext0\base\sashelp" "!sasext0\dquality\sashelp« )
- -PATH ( "!sasext0\dbcs\sasexe" "!sasroot\core\sasexe" "!sasext0\dquality\sasexe" "!sasext0\dmine\sasexe" )
DM "odsresults ; clear" ;
proc tabulate data=data.tab3 missing ; class cat ; class sonf; tables sonf all='Total',cat*(n*f=10.0 pctn='%'*f=10.1) all='Total'*(n*f=10.0 pctn='%'*f=10.1) ; run ;où chaque variable (comme ici "sonf") est traitée en fonction de la variable "cat". Je voudrais à chaque fois récupérer le risque relatif (proc freq option cmh) et sous chaque tableau écrire : "Le risque relatif est : ....". Comment faire? Merci d'avance. voici un exemple de réponse :
- avec une proc Freq (et l'option RELRISK plutôt que CMH plus bavarde), calculer les risques relatifs. Ceux-ci sont édités dans un objet ODS appelé RelativeRisks (si vous utilisez CMH, l'objet se nomme CommonRelRisks)
- ajouter, juste au-dessus de la proc Freq, une instruction ODS OUTPUT pour récupérer ces informations dans une table SAS
- après la proc Freq, ajouter une étape Data pour générer une macro-variable contenant la valeur du risque relatif qui vous intéresse
- se servir de la valeur de cette macro-variable dans un FOOTNOTE ou un ODS TEXT.
ODS EXCLUDE ALL ; ODS OUTPUT relativeRisks = work.rr ; PROC FREQ DATA = cours.produits ; TABLE couleur * primeur / RELRISK ; RUN ; ODS SELECT ALL ; DATA _NULL_ ; SET work.rr (WHERE = (studyType = "Case-Control (Odds Ratio)")) ; CALL SYMPUT ("rr", LEFT(PUT(value, 12.2))) ; RUN ; ODS RTF FILE = "c:\temp\essai.doc" STARTPAGE = NEVER ; PROC TABULATE DATA = cours.produits ; CLASS couleur primeur ; TABLE (couleur ALL="TOTAL") , (primeur ALL="TOTAL") * (N * F = 7. colPctN = "%" * F = 7.1) ; RUN ; ODS RTF TEXT = "Le risque relatif est : &rr" ; ODS RTF CLOSE ;Par rapport au programme de votre question, je préfère l'emploi des mots-clés PCTN, COLPCTN et ROWPCTN à celui des spécifications entre < et > du dénominateur de ces pourcentages ; PCTN sont des pourcentages de l'ensemble du tableau, COLPCTN des pourcentages-colonnes et ROWPCTN des pourcentages-lignes.
STARTPAGE = NOLes sorties de vos procédures (graphiques ou tableaux) se trouveront à la suite les unes des autres, sans sauts de pages.
PROC GCHART DATA = sashelp.class ; VBAR sex / SUMVAR = age TYPE = MEAN DES = "Moyenne d'âge par sexe" ; RUN ; QUIT ;
- de filtrer les données en amont avec un WHERE
- d'utiliser un format pour associer les valeurs des valeurs des variables CLASS à ne pas afficher avec des valeurs manquantes (par défaut, la procédure Tabulate n'affiche pas les valeurs manquantes)
PROC TABULATE DATA = ... FORMAT = NUMX12.2 ;devrait faire l'affaire.
proc format; value pop (multilabel) low-35="35 ans et moins" low-high/* ?? */="tout le monde"; run;mais si j'applique ce format dans une proc freq par exemple:
proc freq data=****; table age; format age pop.; run;j'obtiens bien les 35 ans et moins d'une part, mais dans "tout le monde" je n'ai que les plus de 35 ans. Comment obtenir l'ensemble de la population? Merci pour votre réponse Bonjour. Il n'est malheureusement pas possible d'utiliser les formats MULTILABEL partout. Seules les procédures MEANS et TABULATE les supportent. Une alternative pour votre problème : dupliquer les observations correspondant aux moins de 35 ans, avec une étape Data.
DATA work.pour_etude ; SET *** ; IF age < 35 THEN DO ; doublon = 1 ; OUTPUT ; END ; doublon = 0 ; /* pour tout le monde */ OUTPUT ; RUN ;Ensuite il suffit d'habiller la variable DOUBLON avec un format : 0 -> tout le monde 1 -> moins de 35 ans.
- pour que les titres des instructions TITLE apparaissent en tête de chaque onglet; ajoutez l'option EMBEDDED_TITLES="YES" aux spécifications d'ODS TAGSETS.EXCELXP
- si vous souhaitez conserver un titre visible à l'impression, vous pouvez l'indiquer avec l'option PRINT_HEADER="ici titre personnalisé", toujours dans l'instruction ODS TAGSETS.EXCELXP.
ODS TAGSETS.EXCELXP FILE="c:\temp\titres.xls" OPTIONS(EMBEDDED_TITLES="YES" PRINT_HEADER="%NRSTR(&E)Tout le classeur porte sur la table SASHELP.CLASS" SHEET_NAME="Détail" SHEET_INTERVAL="PROC") ; TITLE1 "Liste des enfants" ; PROC PRINT DATA=sashelp.class NOOBS ; RUN ; ODS TAGSETS.EXCELXP OPTIONS(SHEET_NAME="Stats") ; TITLE1 "Statistiques" ; PROC FREQ DATA=sashelp.class ; TABLE sex age ; RUN ; TITLE ; ODS TAGSETS.EXCELXP CLOSE ;
ODS RTF FILE="c:\temp\test vertical.doc" ; PROC REPORT DATA=sashelp.shoes SPLIT=" " NOWD ; COLUMNS _ALL_ ; RUN ; ODS RTF CLOSE ;Ici l'espace sert d'indication pour revenir à la ligne, mais on peut modifier les labels pour incruster à l'endroit voulu (y compris après chaque lettre !) un caractère de retour à la ligne.
PROC CONTENTS DATA=sashelp.shoes OUT=work.labels (KEEP=name label) NOPRINT ; RUN ; DATA _NULL_ ; SET work.labels END=fin ; LENGTH newLabel $ 200 ; newLabel = PRXCHANGE("s/(.)/¤$1/",-1,STRIP(COALESCEC(label,name))) ; newLabel = SUBSTR(newLabel,2) ; /* élimine le 1er ¤ ajouté en tête */ IF _N_=1 THEN CALL EXECUTE ("DATA work.export ; SET sashelp.shoes ; LABEL ") ; CALL EXECUTE (name !! "=" !! QUOTE(STRIP(newLabel))) ; IF fin THEN CALL EXECUTE ("; RUN ;") ; RUN ; ODS RTF FILE="c:\temp\test vertical.doc" ; PROC REPORT DATA=work.export SPLIT="¤" NOWD ; COLUMNS _ALL_ ; RUN ; ODS RTF CLOSE ;
proc template; define style styles.noborder; parent=styles.minimal; style Pays / just = center; end; run; ODS HTML FILE='Edition.xls' STYLE=styles.noborder; title; Proc print data=final noobs; Run; ods HTML close ;Merci d'avance. Je vous conseillerais d'aller agir directement dans la procédure Print, qui le permet, plutôt que dans la procédure Template, qui accepte mal les cas particuliers de mise en forme par colonne.
ODS HTML FILE='Edition.xls' STYLE=minimal ; TITLE ; PROC PRINT DATA=final NOOBS ; VAR entite ; VAR pays / STYLE = [JUST=CENTER] ; VAR ; RUN ; ODS HTML CLOSE ;Attention cependant, selon les versions, Excel n'applique pas toujours les consignes de centrage. Si vous possédez SAS 9 et Excel 2003, je vous conseille plutôt de passer par la destination ODS TAGSETS.EXCELXP que par ODS HTML.
ODS ODS TAGSETS.EXCELXP FILE='Edition.xls' STYLE=minimal ; title; Proc print data=final noobs; VAR entite ; VAR pays / STYLE = [JUST=CENTER] ; VAR ; Run; ods ODS TAGSETS.EXCELXP close ;
- pour toutes versions de SAS depuis la 8.0, vous pouvez ouvrir une destination ODS HTML sur le même principe qu'ODS RTF, en indiquant dans FILE= un fichier dont l'extension est .XLS. Vous ne créerez pas une feuille Excel au sens strict, mais une page Web qu'Excel sait lire à partir de la version 1997
- pour SAS 9.1 et Excel 2003 minimum, vous pouvez utiliser ODS TAGSETS.EXCELXP qui va créer un (presque) véritable classeur Excel. La documentation sur cette destination et ses options peut s'afficher dans la fenêtre Log en exécutant le programme suivant :
ODS TAGSETS.EXCELXP OPTIONS(DOC="help") FILE = "c:\temp\rien.xls" ;
- pour SAS 9.4 et Excel 2007 minimum, vous pouvez utiliser ODS EXCEL qui va créer un véritable classeur Excel d'extension XLSX.
ODS HTML FILE = "chemin et nom de votre fichier.xls" ; TITLE ; FOOTNOTE ; PROC PRINT DATA = votre_table LABEL NOOBS ; RUN ; ODS HTML CLOSE ;Vous obtiendrez ainsi une pseudo feuille Excel (en fait, c'est une page Web habillée d'une extension XLS, mais Excel 97 n'y verra que du feu). En revanche, pour pouvoir ajouter d'autres feuilles au classeur par la suite, il est recommandé d'ouvrir Excel, d'ouvrir la feuille créée et de la sauvegarder en forçant son type à "Classeur Excel". Plus proprement, mais uniquement si vous possédez le module ACCESS TO PC FILES, vous pouvez exporter directement dans une vraie feuille Excel ainsi :
PROC EXPORT DATA = votre_table OUTFILE = "chemin et nom de votre fichier.xls" REPLACE DBMS = EXCEL97 ; RUN ;Pour savoir si vous possédez ledit module, exécutez le programme suivant :
PROC SETINIT NOALIAS ; RUN ;et regardez dans la Log. Si une ligne "SAS/ACCESS Interface to PC Files" y apparaît (ou un intitulé approchant, il varie selon les versions), c'est bon. Sinon, il faudra opter pour la première solution.
ods rtf body = "c:\temp\essai.doc" ; proc print data = grosse.table ; run ; ods rtf close ; options noxwait ; x "start winword" ; DATA _null_ ; BIDON = sleep(10) ; /* attente de l'ouverture de Word */ RUN ; filename word DDE "winword|system" ; DATA _null_ ; FILE word ; PUT '[FileOpen .name="C:\temp\essai.doc"]' ; /* ouverture du document Word */ PUT '[FileSaveAs .Name="essai.htm" .Format=wdFormatHTML]' ; /* enregistrement au format HTML */ PUT '[FileExit 1]' ; /* fermeture de Word */ RUN ;
- remplacer tous les points du tableau par des virgules sous Excel (avec un Remplacer)
- changer le séparateur décimal (Menu Démarrer de Windows, Panneau de Configuration, Paramètres Régionaux, onglet Nombres) de la virgule pour le point.
- si le tableau est généré par une PROC TABULATE, rajouter à l'instruction TABLE qu'il faut employer des formats NUMXx.y, qui fonctionnent comme les formats numériques x.y habituels, mais affichent une virgule comme séparateur décimal ! Pour cela, la commande à insérer est *format=NUMX12.2 par exemple.
- si le tableau est généré par une PROC PRINT, une PROC TABULATE ou une PROC REPORT, utiliser les instructions de formatage avec l'attribut de style TAGATTR qui permet d'envoyer à Excel des indications de format de cellule (cf. L'export de SAS vers Excel expliqué à ma fille)
Performance
- attention à ne pas confondre LENGTH et FORMAT ; le premier est le nombre d'octets sur lequel une valeur est stockée et le second une indication de la manière dont les valeurs sont affichées. Dans le cas d'une variable caractère, les deux sont souvent semblables : une variable stockée sur 3 octets s'affiche sur 3 caractères (LENGTH=$ 3 et FORMAT=$3.). Pour les variables numériques, on a un LENGTH de 8 (par défaut) et un affichage assez libre : BEST12. signifie juste que SAS utilisera au plus 12 caractères pour afficher la valeur. Le LENGTH de 8 est approprié si la variable contient des décimales. Sinon, selon son ordre de grandeur, on peut gagner de la place avec un LENGTH plus court, entre 3 et 7.
- la compression n'est pas un moyen de gagner du TEMPS mais de la PLACE. Je n'ai pas l'impression que ce soit votre but ; en effet, une table compressée (zippée en interne par SAS) nécessite plus de temps à s'ouvrir (il faut la décompresser) et à s'écrire (il faut la recompresser). Ce n'est donc pas forcément la solution espérée.
Est-ce normal que pour 100 000 lignes, SEM indique le message d'erreur suivant : out of resources ?
Il ne faut pas trop charger SEM dans une configuration avec un serveur qui n'a pas une grosse capacité. Le mieux, c'est de le faire monter en charge progressivement, pour voir où il casse. Dans l'absolu, je ne peux pas dire "100000 c'est trop" ou "100000 ça devrait passer". D'une fois sur l'autre, je n'ai pas les mêmes résultats sur mon propre PC.
Il faut savoir cependant que SEM demande surtout deux choses : de l'espace disque pour entreposer ses multiples tables temporaires (il faut donc choisir de domicilier son projet dans un endroit où la place libre ne manque pas et où il n'existe pas de quotas) et surtout, pour l'exécution des tâches, de la mémoire vive. Mieux vaut donc une machine (serveur ou PC en "stand-alone", c'est à dire sans faire de client/serveur) avec beaucoup de mémoire vive (ajouter des barettes, fermer les autres applications, etc...) qu'avec un ou plusieurs processeurs très rapides, car la puissance de calcul passe après (il lui faut en tout premier lieu de la place) ; de plus, avant la version 9.0, SAS (et a fortiori SEM) ne sait pas profiter d'un multi-processeur.
Bonjour, Voilà mon souci : je voudrais faire une Classification sur une énorme base (env 2 millions de lignes). Ce sont des données qualitatives, alors je dois passer par une ACM, donc construire un Tableau Disjonctif Complet (en tout j'ai 3 variables et 11*97*18 modalités). Seulement SAS bloque un peu beaucoup (il a mouliné toute la nuit et n'a pas avancé...)! La proc transreg que vous proposez dans cette FAQ n'est-elle pas appropriée ici? Ma base est-elle trop volumineuse pour un tel traitement? Si oui, comment faire ma classification? Merci beaucoup pour votre éclairage!
Deux pistes à explorer pour que votre traitement puisse se faire dans un temps acceptable (et, vu vos volumes, se faire tout court !).
1) travailler uniquement sur un échantillon : au lieu des 2 millions de lignes, vous pourriez construire une typologie sur seulement 10% d'entre eux, et ensuite chercher les règles de construction des classes (par un modèle statistique, ou plus simplement par une caractérisation univariée) pour dispatcher l'ensemble de vos lignes dans les différentes classes. 2) réduire le nombre de modalités d'une de vos valeurs : 97 valeurs me paraît un nombre un peu excessif. D'autant que cela risque de déséquilibrer fortement l'ACM (les premiers axes se concentreront sur l'information contenue dans cette variable et pas dans les 2 autres) Vous pourriez faire un recodage pour vous ramener à une vingtaine de valeurs ; non seulement ça équilibre l'ACM, mais en plus la taille des fichiers à traiter (tableau disjonctif complet en entrée de la procédure Corresp, et le tableau de Burt qu'elle construit en interne) sera plus raisonnable. Comment faire votre recodage ? Déjà sur des critères métier, je pense. Et également en faisant une ACM sur cette variable uniquement, dans l'espace des variables seulement, de préférence sur un échantillon aléatoire de vos deux millions de lignes. Pour cette ACM préalable, la syntaxe SAS est la suivante :PROC CORRESP DATA = votreTableSAS MCA SHORT ; TABLES votreVariableA97Modalites ; RUN ;
Si vous avez une version 9 de SAS, vous pouvez ajouter les deux instructions suivantes avant la procédure correspondante :
ODS GRAPHICS ON ; ODS HTML FILE = "c:\temp\sorties ACM.htm" GPATH = "c:\temp" (URL=NONE) ; Et ODS HTML CLOSE ;
après l'instruction RUN ; à la fin du programme.
Non seulement vos sorties seront plus jolies dans une page Web (changer éventuellement c:\temp pour un autre répertoire dans les deux options qui y font référence) mais en plus ODS GRAPHICS ajoutera directement le premier plan factoriel dans l'espace des variables : il ne vous reste "qu'à" fusionner les modalités qui sont proches dans ce plan.Régression
- choisir un seuil pour transformer les prédictions continues (le score) en prédictions binaires (par exemple : 0,5 : si P_1 < 0,5 alors Ypredit = 0, sinon Ypredit=1)
- calculer la nouvelle variable binaire Ypredit
- la croiser (dans une proc Freq) avec la variable Yobservé
- additionner les pourcentages (2e ligne de chaque case) des cellules dans la diagonale du tableau (correspondances entre Yobservé et Y prédit).
CLASS variablesQuali / PARAM = GLM ;donne des coefficients de référence égaux à zéro. C'est le choix par défaut dans GENMOD.
CLASS variablesQuali / PARAM = REF ;donne des contraintes pour que l'ensemble des coefficients d'une variable qualitative soit nul. C'est le choix par défaut dans LOGISTIC.
PROC GLM DATA = tableSAS ; CLASS listeVariablesQuali ; MODEL variableY = listeVariablesQuantiEtQuali / ESTIMATE ; LSMEANS variableQuali / PDIFF=ALL ; RUN ; QUIT ;Une remarque : si le nombre d'observations sur lesquelles vous modélisez est faible, trop de modalités à vos variables qualitatives risquent de faire baisser la robustesse de votre modèle, et alors sans doute faudra-t-il fusionner des modalités... Dans ce cas, les comparaisons 2 à 2 de modalités peuvent vous aider (instruction LSMEANS ci-dessus). Une seconde remarque : si la distribution de vos prix à modéliser suit une loi normale, les procédures REG et GLM sont effectivement appropriées. S'ils suivent plutôt une loi Gamma, il faudra passer à la procédure GENMOD.
- Dans la partie Fit Statistics, on retrouve les critères d'Akaike, de Schwartz et la log-vraisemblance
- Dans la partie Global Tests, on a les tests du chi2 associés au score, à la log-vraisemblance et à la statistique de Wald
MODEL Y = covariables / CTABLE PPROB = (listeDeSeuils) ;
OUTPUT OUT = table PRED = variableP ;on a dans variableP les valeurs prédites pour les données inconnues (ce qu'on appelle un score). Ces valeurs s'échelonnent de 0 à 1, on les lit comme des probabilités d'occurrence d'un évènement. A partir de SAS 9.3, on peut aussi utiliser l'instruction SCORE.
- Type I SS
- Type II SS
- Type III SS
- Types I et III : sommes de carrés sur les EFFETS SIMPLES. C'est à dire la contribution de chacune des variables explicatives, sans les croiser entre elles. Le type I les introduit dans le même ordre que dans l'instruction MODEL, tandis que le type III corrige le biais dû à cet ordre (en fait, c'est comme s'il n'en tenait pas compte).
- Types II : il inclut les effets croisés.
- Type IV : il permet de prendre en compte les données "trouées" (certains cas de figures ne se présentent pas).
ODS OUTPUT OddsRatios = nomTableSAS ;Pour fonctionner, il faut que cette instruction soit entre les instructions PROC LOGISTIC et RUN.
ODS OUTPUT ANOVA = work.maTable ; PROC REG DATA = ... ; ... RUN ; QUIT ;
ODS OUTPUT parameterEstimates = work.coeffs ;et vous retrouverez dans la table COEFFS de la bibliothèque WORK vos coefficients.
PLOT varY * varX = varGroupe ;permet d'obtenir plusieurs séries de points correspondant à différents groupes d'observations.
SYMBOL i = rl v = dot ; PROC GPLOT DATA = sashelp.class ; PLOT weight * height = sex ; RUN ; QUIT ;
Je ne trouve pas la même note de score que SEM lors de la régression... En fait moi je considère que quand par exemple sur une variable à 2 modalités l'individu a la modalité 2 le coefficient de cette modalité 2 est égal à zéro alors que SEM prend comme coeff -(le coeff de la modalité 1)... Exemple pour la variable détention de sécurité12, on a 2 modalités sec1 et sec2.. Sur la grille des coefficients, le coeff de sec1=0.23 et dans ce cas si un individu a la modalité 2, SEM va lui mettre un coeff de -0.23 alors que moi je lui mettrais zéro... Ma question est : de quelle théorie sort-il cette règle? et qu'est ce que ça change et qui a raison?
Il s'agit d'une des petites subtilités du noeud régression : il fonctionne selon deux types de codage, donc d'évaluation des paramètres... Le premier, appelé DEVIATION, est celui par défaut. Il contraint la somme des paramètres à faire toujours 0, d'où l'obligation de prendre l'opposé comme coefficient du niveau de référence quand on a une variable binaire. Le second modèle de codage, GLM, est celui qu'on a l'habitude de manipuler. (Y compris dans les procédures REG et LOGISTIC.) Il consiste à mettre 0 pour la modalité de référence, et à donner les autres coeffs en fonction. Comme toujours, sur les fondements théoriques de leurs implémentations, les docs SAS restent d'une louable discrétion. En revanche, comment se débarrasser de ce codage bizarre ? Il suffit de cocher la case INPUT CODING = GLM au lieu du défaut INPUT CODING = DEVIATION. Cela se passe dans l'onglet MODEL OPTIONS, sous-onglet REGRESSION, dans le paramétrage de ce noeud.
Bonjour,
Habituellement, quand je fais une régression, je travaille sur une variable binaire. En amont, je construis donc un échantillon 50-50 (50% de détenteurs // 50% de non détenteurs). Aujourd'hui, je dois réaliser une régression sur une variable continue mais je ne sais pas comment procéder pour réaliser un échantillon. S'agit-il d'un tirage aléatoire ?
Merci d'avance pour votre réponse.
Bonjour.
Pour une régression linéaire, il n'y a pas d'intérêt particulier à pratiquer un échantillonnage "orienté" au préalable. Un échantillon aléatoire est amplement suffisant si vous disposez de données trop volumineuses. En outre, travailler sur de plus faibles volumes de données vous permettra d'avoir des p-values plus réalistes pour les divers tests associés au modèle linéaire (Fisher, coefficients du modèle) que sur des milliers d'observations qui fournissent presque toujours des p-values inférieures à 0,0001.
Deux contraintes sont en revanche très importantes à satisfaire dans le cadre du modèle linéaire :
- la variable Y expliquée doit suivre une loi normale, ou au moins être unimodale (un seul pic de fréquence parmi ses modalités) et à peu près symétrique. Sinon, vous devez la transformer (avec un logarithme par exemple si elle est asymétrique) ou vous tourner vers un modèle linéaire généralisé (PROC GENMOD de SAS) qui vous permettra de préciser une autre loi que la loi normale pour Y ;
- les variables explicatives doivent être autant que possibles indépendantes les unes des autres. Comme dans tous les modèles linéaires, la multicolinéarité engendre de grandes instabilités dans les coefficients du modèle. La procédure REG propose des critères comme le VIF pour évaluer la multicolinéarité, à condition de travailler uniquement sur des variables explicatives quantitatives. Si ce n'est pas le cas et que vous utilisez la PROC GLM, alors une étude préalable des liaisons entre variables (ACM, tests du chi-2) serait la bienvenue.
Bonjour et merci d'avoir répondu à mes précédentes questions.
Ma régression logistique concerne 39 651 individus. J'ai donc, dans un premier temps, effectué un échantillon équilibré à 50/50 et j'obtiens 2 204 individus (car 1 201 ont la modalité cible égale à 1). Par la suite il est nécessaire de réaliser un partitionnement 70/30. On m'a conseillé de prendre 70% pour l'entrainement et 30% pour la validation. Ce que je voudrais savoir c'est comment faire ce partitionnement sous SAS (et non Miner) ? Faut-il que les deux partitions soient elles aussi équilibrées en fonction de la cible (35% -- >0 et 35% -->1 pour l'entrainement et 15% -->0 et 15% -->1 ) ? Et à quel moment la partition à 30% va t-elle intervenir pour la validation ?
D'autre part, pour le seuil optimal, j'obtiendrai forcément 0,5 puisque mon échantillon est équilibré ? Cela n'est pas gênant ?
Le fait de travailler sur 70% des 2 204 individus ne fausse pas le modèle ?
Je vous remercie pour votre réponse.
Bonjour.
Partition 70/30 :
DATA work.train work.valid ; SET maBase ; alea = RANUNI(0) ; IF alea < .7 THEN OUTPUT work.train ; ELSE OUTPUT work.valid ; RUN ;
Seuil optimal :
Il sera sans doute aux alentours de 0,5, pas forcément exactement à cette valeur. En fait, le seuil optimal s'harmonise avec la valeur de la constante du modèle, ce ne sera donc pas faux de travailler ensuite sur une population non équilibrée avec ce seuil.
Volume de données :
70% de 2200 individus, ça en fait encore largement assez, sauf si vous avez 400 variables explicatives dans votre modèle.
Utilisation des données de validation :
On ne construit pas de modèle dessus, on se contente de leur appliquer le moteur de score (c'est à dire qu'on prédit avec le modèle). Et on comparer le taux de bien classés avec celui donné par les données d'entraînement. Ce taux est plus fiable (l'autre est biaisé vers 0), et la constance du taux est signe de robustesse.
Suite à une modélisation de variable binaire, j'utilise la PROC LOGISTIC de SAS 8.2. - Pour espérer obtenir de meilleurs résultats, faut-il équilibrer ma population de clients et de non clients? Exemple: expliquer une situation Y=1 alors que 80% de la population étudiée a Y=1, donne-t-il un poids trop important à ce groupe de clients ? - L'équilibre doit-il se faire dans l'échantillon d'apprentissage (70% de la population totale) sans s'en occuper dans l'échantillon test? - Après avoir obtenu les coefficients estimés du modèle sur les variables explicatives significatives dans le journal via la procédure ou sous EM, comment puis-je appliquer ce modèle sur une autre population (présentant évidemment les mêmes variables explicatives) afin de tous les attribuer un score? Suis-je obligée de faire cette étape manuellement ? Merci beaucoup de votre aide.
Il est toujours préférable de travailler sur un échantillon équilibré. Pour pouvoir comparer les performances de votre modèle sur le corpus d'apprentissage et sur celui de test, il est préférable que les deux soient équilibrés.
L'utilisation des coefficients du modèle peut se faire via la procédure SCORE si les variables explicatives de votre modèle sont quantitatives, ou des indicatrices. La prise en compte par la proc SCORE des variables quali est très mauvaise. Sinon, il est possible d'effectuer automatiquement ces manipulations en écrivant un petit macro-programme.
A noter qu'à partir de la version 9, la proc LOGISTIC intègre une instruction pour préciser une table SAS à scorer.
Bonjour,
J'aimerais effectuer un arbre de régression, à savoir un arbre avec une cible quantitative. Cela est-il possible avec Sas EM? Et si oui, comment? Les arbres de décisions sont-ils possibles avec Sas Guide ou Sas Base? Merci pour votre aide.
Oui, il est possible d'utiliser SAS EM pour construire des arbres de régression. Pour cela, il suffit de déclarer comme variable cible une variable quantitative (type = INTERVAL) dans le nœud INPUT DATA SOURCE. Ensuite, SEM propose dans le nœud TREE deux types d'arbres : celui dérivé de CART qui choisit les coupures sur une réduction de la variance intra-nœuds, et celui dérivé de CHAID qui choisit les coupures avec un test de Fisher (F test).
La procédure mise en œuvre est la proc ARBORETUM (dans SAS 9) ou la proc DMSPLIT (dans SAS v8). Ces procédures ne sont disponibles qu'avec une licence SAS EM. Donc on ne peut pas les utiliser avec seulement une licence SAS Base ou SAS/STAT. Cependant, ces procédures ont une syntaxe (certes non documentée) donc peuvent être incluses dans des programmes et des macros qu'on exécutera directement depuis SAS PC ou SAS Enterprise Guide.
Reporting
PROC FORMAT ; VALUE $prod "TABLE" = "VERY LONG VALUE INSTEAD OF JUST ""TABLE"" " ; RUN ; ODS RTF FILE="c:\temp\sans uniform.doc" ; ODS TAGSETS.RTF FILE="c:\temp\avec uniform.doc" UNIFORM ; PROC REPORT DATA=sashelp.prdsale NOWD ; COLUMNS year month product actual predict ; FORMAT product $prod. ; DEFINE year / DISPLAY ; RBREAK BEFORE / SUMMARIZE ; RUN ; ODS RTF CLOSE ; ODS TAGSETS.RTF CLOSE ;
ODS TRACE ON / LISTING ; PROC xxx ... ; ... RUN ; ODS TRACE OFF ;Les informations sur chaque objet s'ajoutent dans la fenêtre Output. Une fois qu'on connaît le nom (QUANTILES pour celui qui vous concerne), on peut écire :
PROC UNIVARIATE ... ; ... ODS OUTPUT quantiles = work.maTableSAS ; RUN ;ou, pour n'afficher que le tableau de quantiles :
ODS SELECT quantiles ; PROC UNIVARIATE ... ; ... RUN ; ODS SELECT ALL ;
ODS EXCLUDE ALL ; PROC TABULATE DATA = ... OUT = ... ; ... RUN ; ODS SELECT ALL ;
- faire précéder le programme de l'option système VALIDVARNAME=ANY qui va autoriser les caractères accentués dans les noms.
- Faire un RENAME dès que possible pour se débarrasser de l'accent et pouvoir repositionner VALIDVARNAME à sa valeur initiale, V7.
OPTION VALIDVARNAME=ANY ; ODS OUTPUT crossTabFreqs = work.maSortie (RENAME = ("Fréquence"n = Frequence)) ; PROC FREQ DATA = ... ; TABLE ... ; RUN ; OPTION VALIDVARNAME=V7 ;
DEFINE ... / ... STYLE(HEADER)=[URL="adresse"] ;
ODS OUTPUT OddsRatios = nomTableSAS ;Pour fonctionner, il faut que cette instruction soit entre les instructions PROC LOGISTIC et RUN.
ODS EXCLUDE ALL ; /* plus aucune sortie sauf ODS OUTPUT */ PROC TTEST ... ; ... ODS OUTPUT ... ; RUN ; ODS SELECT ALL ; /* retour à la normale */
ODS OUTPUT ANOVA = work.maTable ; PROC REG DATA = ... ; ... RUN ; QUIT ;
ODS OUTPUT parameterEstimates = work.coeffs ;et vous retrouverez dans la table COEFFS de la bibliothèque WORK vos coefficients.
ODS TRACE ON ; PROC xxx ... ; ... RUN ; ODS TRACE OFF ;Dans la fenêtre LOG, chaque morceau des sorties correspond à un cartouche indiquant, entre autres (ligne NAME), le nom de l'objet ODS produit.
ods html body='c:\essai.htm' (title="~~~~~~ Tableau de bord direction financière ~~~~~~"); proc print data=sashelp.class; run; ods html close;
/* partie 1 : modifier le Registry */ data _null_ ; file "c:\temp\regtemp.reg" ; put "[ODS\PREFERENCES\HTML]" / "'AutoNavigate'=int:0" ; run ;
proc registry import = "c:\temp\regtemp.reg" ; run ;
/* étape 2 : le traitement pour lequel on ne veut pas avoir le résultat présenté spontanément */
/* étape 3 : remettre le Registry à sa valeur par défaut */ proc registry uninstall = "c:\temp\regtemp.reg" ; run ;
- on fait précéder de CX les codes RGB sans signe dièse
- on peut aussi utiliser des nuances de gris, de GRAY00 à GRAYFF
... style = { background = CX0000FF }Note : il n'est pas nécessaire d'avoir une licence SAS/GRAPH pour que cela fonctionne.
ODS HTML BODY = ... STYLESHEET = "mon_fic.css" ;Ce fichier .css, qu'on appelle une feuille de style, permet de définir nombre de polices, couleurs, etc... Il peut se mettre en commun à plusieurs pages Web (d'où un gain de place). On peut aussi utiliser un des nombreux styles prédéfinis de SAS.
PROC TEMPLATE ; LIST styles ; RUN ;
- - DBCS
- - DBCSTYPE PCMS
- -SASHELP ( "!SASCFG\SASCFG" "!sasext0\dbcs\sashelp" "!sasroot\core\sashelp" "!sasext0\base\sashelp" "!sasext0\dquality\sashelp« )
- -PATH ( "!sasext0\dbcs\sasexe" "!sasroot\core\sasexe" "!sasext0\dquality\sasexe" "!sasext0\dmine\sasexe" )
DM "odsresults ; clear" ;
proc tabulate data=data.tab3 missing ; class cat ; class sonf; tables sonf all='Total',cat*(n*f=10.0 pctn='%'*f=10.1) all='Total'*(n*f=10.0 pctn='%'*f=10.1) ; run ;où chaque variable (comme ici "sonf") est traitée en fonction de la variable "cat". Je voudrais à chaque fois récupérer le risque relatif (proc freq option cmh) et sous chaque tableau écrire : "Le risque relatif est : ....". Comment faire? Merci d'avance. voici un exemple de réponse :
- avec une proc Freq (et l'option RELRISK plutôt que CMH plus bavarde), calculer les risques relatifs. Ceux-ci sont édités dans un objet ODS appelé RelativeRisks (si vous utilisez CMH, l'objet se nomme CommonRelRisks)
- ajouter, juste au-dessus de la proc Freq, une instruction ODS OUTPUT pour récupérer ces informations dans une table SAS
- après la proc Freq, ajouter une étape Data pour générer une macro-variable contenant la valeur du risque relatif qui vous intéresse
- se servir de la valeur de cette macro-variable dans un FOOTNOTE ou un ODS TEXT.
ODS EXCLUDE ALL ; ODS OUTPUT relativeRisks = work.rr ; PROC FREQ DATA = cours.produits ; TABLE couleur * primeur / RELRISK ; RUN ; ODS SELECT ALL ; DATA _NULL_ ; SET work.rr (WHERE = (studyType = "Case-Control (Odds Ratio)")) ; CALL SYMPUT ("rr", LEFT(PUT(value, 12.2))) ; RUN ; ODS RTF FILE = "c:\temp\essai.doc" STARTPAGE = NEVER ; PROC TABULATE DATA = cours.produits ; CLASS couleur primeur ; TABLE (couleur ALL="TOTAL") , (primeur ALL="TOTAL") * (N * F = 7. colPctN = "%" * F = 7.1) ; RUN ; ODS RTF TEXT = "Le risque relatif est : &rr" ; ODS RTF CLOSE ;Par rapport au programme de votre question, je préfère l'emploi des mots-clés PCTN, COLPCTN et ROWPCTN à celui des spécifications entre < et > du dénominateur de ces pourcentages ; PCTN sont des pourcentages de l'ensemble du tableau, COLPCTN des pourcentages-colonnes et ROWPCTN des pourcentages-lignes.
STARTPAGE = NOLes sorties de vos procédures (graphiques ou tableaux) se trouveront à la suite les unes des autres, sans sauts de pages.
PROC GCHART DATA = sashelp.class ; VBAR sex / SUMVAR = age TYPE = MEAN DES = "Moyenne d'âge par sexe" ; RUN ; QUIT ;
- de filtrer les données en amont avec un WHERE
- d'utiliser un format pour associer les valeurs des valeurs des variables CLASS à ne pas afficher avec des valeurs manquantes (par défaut, la procédure Tabulate n'affiche pas les valeurs manquantes)
PROC TABULATE DATA = ... FORMAT = NUMX12.2 ;devrait faire l'affaire.
OPTION LOCALE = FRENCH ;par exemple en début de programme SAS, en dehors de toute procédure et étape Data.
proc format; value pop (multilabel) low-35="35 ans et moins" low-high/* ?? */="tout le monde"; run;mais si j'applique ce format dans une proc freq par exemple:
proc freq data=****; table age; format age pop.; run;j'obtiens bien les 35 ans et moins d'une part, mais dans "tout le monde" je n'ai que les plus de 35 ans. Comment obtenir l'ensemble de la population? Merci pour votre réponse Bonjour. Il n'est malheureusement pas possible d'utiliser les formats MULTILABEL partout. Seules les procédures MEANS et TABULATE les supportent. Une alternative pour votre problème : dupliquer les observations correspondant aux moins de 35 ans, avec une étape Data.
DATA work.pour_etude ; SET *** ; IF age < 35 THEN DO ; doublon = 1 ; OUTPUT ; END ; doublon = 0 ; /* pour tout le monde */ OUTPUT ; RUN ;Ensuite il suffit d'habiller la variable DOUBLON avec un format : 0 -> tout le monde 1 -> moins de 35 ans.
PROC FORMAT ; PICTURE milliers (ROUND) 0 - HIGH = "000 000 009" ; RUN ;Vous utilisez ensuite le format milliers. quand vous en avez besoin. Pour plus d'informations sur les formats "picture", voir Les pictures expliqués à ma fille.
- pour que les titres des instructions TITLE apparaissent en tête de chaque onglet; ajoutez l'option EMBEDDED_TITLES="YES" aux spécifications d'ODS TAGSETS.EXCELXP
- si vous souhaitez conserver un titre visible à l'impression, vous pouvez l'indiquer avec l'option PRINT_HEADER="ici titre personnalisé", toujours dans l'instruction ODS TAGSETS.EXCELXP.
ODS TAGSETS.EXCELXP FILE="c:\temp\titres.xls" OPTIONS(EMBEDDED_TITLES="YES" PRINT_HEADER="%NRSTR(&E)Tout le classeur porte sur la table SASHELP.CLASS" SHEET_NAME="Détail" SHEET_INTERVAL="PROC") ; TITLE1 "Liste des enfants" ; PROC PRINT DATA=sashelp.class NOOBS ; RUN ; ODS TAGSETS.EXCELXP OPTIONS(SHEET_NAME="Stats") ; TITLE1 "Statistiques" ; PROC FREQ DATA=sashelp.class ; TABLE sex age ; RUN ; TITLE ; ODS TAGSETS.EXCELXP CLOSE ;
ODS RTF FILE="c:\temp\test vertical.doc" ; PROC REPORT DATA=sashelp.shoes SPLIT=" " NOWD ; COLUMNS _ALL_ ; RUN ; ODS RTF CLOSE ;Ici l'espace sert d'indication pour revenir à la ligne, mais on peut modifier les labels pour incruster à l'endroit voulu (y compris après chaque lettre !) un caractère de retour à la ligne.
PROC CONTENTS DATA=sashelp.shoes OUT=work.labels (KEEP=name label) NOPRINT ; RUN ; DATA _NULL_ ; SET work.labels END=fin ; LENGTH newLabel $ 200 ; newLabel = PRXCHANGE("s/(.)/¤$1/",-1,STRIP(COALESCEC(label,name))) ; newLabel = SUBSTR(newLabel,2) ; /* élimine le 1er ¤ ajouté en tête */ IF _N_=1 THEN CALL EXECUTE ("DATA work.export ; SET sashelp.shoes ; LABEL ") ; CALL EXECUTE (name !! "=" !! QUOTE(STRIP(newLabel))) ; IF fin THEN CALL EXECUTE ("; RUN ;") ; RUN ; ODS RTF FILE="c:\temp\test vertical.doc" ; PROC REPORT DATA=work.export SPLIT="¤" NOWD ; COLUMNS _ALL_ ; RUN ; ODS RTF CLOSE ;
proc template; define style styles.noborder; parent=styles.minimal; style Pays / just = center; end; run; ODS HTML FILE='Edition.xls' STYLE=styles.noborder; title; Proc print data=final noobs; Run; ods HTML close ;Merci d'avance. Je vous conseillerais d'aller agir directement dans la procédure Print, qui le permet, plutôt que dans la procédure Template, qui accepte mal les cas particuliers de mise en forme par colonne.
ODS HTML FILE='Edition.xls' STYLE=minimal ; TITLE ; PROC PRINT DATA=final NOOBS ; VAR entite ; VAR pays / STYLE = [JUST=CENTER] ; VAR ; RUN ; ODS HTML CLOSE ;Attention cependant, selon les versions, Excel n'applique pas toujours les consignes de centrage. Si vous possédez SAS 9 et Excel 2003, je vous conseille plutôt de passer par la destination ODS TAGSETS.EXCELXP que par ODS HTML.
ODS ODS TAGSETS.EXCELXP FILE='Edition.xls' STYLE=minimal ; title; Proc print data=final noobs; VAR entite ; VAR pays / STYLE = [JUST=CENTER] ; VAR ; Run; ods ODS TAGSETS.EXCELXP close ;
- pour toutes versions de SAS depuis la 8.0, vous pouvez ouvrir une destination ODS HTML sur le même principe qu'ODS RTF, en indiquant dans FILE= un fichier dont l'extension est .XLS. Vous ne créerez pas une feuille Excel au sens strict, mais une page Web qu'Excel sait lire à partir de la version 1997
- pour SAS 9.1 et Excel 2003 minimum, vous pouvez utiliser ODS TAGSETS.EXCELXP qui va créer un (presque) véritable classeur Excel. La documentation sur cette destination et ses options peut s'afficher dans la fenêtre Log en exécutant le programme suivant :
ODS TAGSETS.EXCELXP OPTIONS(DOC="help") FILE = "c:\temp\rien.xls" ;
- pour SAS 9.4 et Excel 2007 minimum, vous pouvez utiliser ODS EXCEL qui va créer un véritable classeur Excel d'extension XLSX.
ODS HTML FILE = "chemin et nom de votre fichier.xls" ; TITLE ; FOOTNOTE ; PROC PRINT DATA = votre_table LABEL NOOBS ; RUN ; ODS HTML CLOSE ;Vous obtiendrez ainsi une pseudo feuille Excel (en fait, c'est une page Web habillée d'une extension XLS, mais Excel 97 n'y verra que du feu). En revanche, pour pouvoir ajouter d'autres feuilles au classeur par la suite, il est recommandé d'ouvrir Excel, d'ouvrir la feuille créée et de la sauvegarder en forçant son type à "Classeur Excel". Plus proprement, mais uniquement si vous possédez le module ACCESS TO PC FILES, vous pouvez exporter directement dans une vraie feuille Excel ainsi :
PROC EXPORT DATA = votre_table OUTFILE = "chemin et nom de votre fichier.xls" REPLACE DBMS = EXCEL97 ; RUN ;Pour savoir si vous possédez ledit module, exécutez le programme suivant :
PROC SETINIT NOALIAS ; RUN ;et regardez dans la Log. Si une ligne "SAS/ACCESS Interface to PC Files" y apparaît (ou un intitulé approchant, il varie selon les versions), c'est bon. Sinon, il faudra opter pour la première solution.
ods rtf body = "c:\temp\essai.doc" ; proc print data = grosse.table ; run ; ods rtf close ; options noxwait ; x "start winword" ; DATA _null_ ; BIDON = sleep(10) ; /* attente de l'ouverture de Word */ RUN ; filename word DDE "winword|system" ; DATA _null_ ; FILE word ; PUT '[FileOpen .name="C:\temp\essai.doc"]' ; /* ouverture du document Word */ PUT '[FileSaveAs .Name="essai.htm" .Format=wdFormatHTML]' ; /* enregistrement au format HTML */ PUT '[FileExit 1]' ; /* fermeture de Word */ RUN ;
- remplacer tous les points du tableau par des virgules sous Excel (avec un Remplacer)
- changer le séparateur décimal (Menu Démarrer de Windows, Panneau de Configuration, Paramètres Régionaux, onglet Nombres) de la virgule pour le point.
- si le tableau est généré par une PROC TABULATE, rajouter à l'instruction TABLE qu'il faut employer des formats NUMXx.y, qui fonctionnent comme les formats numériques x.y habituels, mais affichent une virgule comme séparateur décimal ! Pour cela, la commande à insérer est *format=NUMX12.2 par exemple.
- si le tableau est généré par une PROC PRINT, une PROC TABULATE ou une PROC REPORT, utiliser les instructions de formatage avec l'attribut de style TAGATTR qui permet d'envoyer à Excel des indications de format de cellule (cf. L'export de SAS vers Excel expliqué à ma fille)
Représentation visuelle
PLOT varY * varX = varGroupe ;permet d'obtenir plusieurs séries de points correspondant à différents groupes d'observations.
SYMBOL i = rl v = dot ; PROC GPLOT DATA = sashelp.class ; PLOT weight * height = sex ; RUN ; QUIT ;
axis1 value=(h=1.5) label=(h=1.5 "^S={font_face=symbol}m ^S={}") offset=(1.5,1.5) length=100 pct;
axis2 value=(h=1.5).......Mais cela ne fonctionne pas, SAS n'interprète pas la police Symbol. Auriez-vous une solution? Merci Les ESCAPECHAR comme vous avez essayé ne fonctionnent que pour les titres gérés par l'ODS. Les axes sont gérés par SAS/GRAPH pour les procédures GPLOT, GCHART ou BOXPLOT. Il vaudrait mieux utiliser la police GREEK fournie par SAS via une option FONT dans la définition du label.
AXIS1 value=(h=1.5) label=(h=1.5 font=GREEK "m" font=swiss "g") offset=(1.5,1.5) length=100 pct;
DATA work.deux ; SET table1 (IN=annee1) table2 (IN=annee2) ; IF annee1 THEN annee = 2005 ; IF annee2 THEN annee = 2006 ; RUN ; PROC GCHART DATA=work.deux ; VBAR variable / SUBGROUP=annee ; RUN ; QUIT ;Globalement, l'idée lors de la fusion des deux tables est de garder une trace de leur origine (avec des IN). On peut choisir d'empiler (SET) ou de joindre (MERGE) les deux tables ; il est plus simple pour l'empilement (options GROUP, SUBGROUP, BY) d'avoir plusieurs séries d'observations, donc un empilement préalable.
STARTPAGE = NOLes sorties de vos procédures (graphiques ou tableaux) se trouveront à la suite les unes des autres, sans sauts de pages.
DATA work.shoes ; SET sashelp.shoes (WHERE = (region IN: ("Africa","Canada","Western"))) ; SELECT (region) ; WHEN ("Canada") ordre = 1 ; WHEN ("Africa") ordre = 2 ; OTHERWISE ordre = 3 ; END ; RUN ; PROC SORT DATA = work.shoes ; BY ordre ; RUN ; PROC BOXPLOT DATA = work.shoes ; PLOT sales * region ; RUN ;
PROC GCHART DATA = sashelp.class ; VBAR sex / SUMVAR = age TYPE = MEAN DES = "Moyenne d'âge par sexe" ; RUN ; QUIT ;
ODS RTF FILE = "..." STARTPAGE = NEVER ; PROC Gxxx ... ; ... RUN ; QUIT ; ODS RTF CLOSE ;
Plateforme / OS | Instruction |
Windows | GOPTION KEYMAP = winansi ; |
Unix / Linux | GOPTION KEYMAP = sas8859 ; |
GOPTIONS HSIZE = 10cm VSIZE = 15cm ; PROC G... ; etc...On peut aussi spécifier les tailles en pouces ("in" après le nombre) ou en points ("pt").
PROC GPLOT DATA = ... ; PLOT y1*x1 y2*x2 ; RUN ; QUIT ;L'option OVERLAY permet de superposer les graphiques... Attention, par défaut, pas de légende (d'où l'astuce de désigner LEGEND1 qui n'existe pas, mais il va se débrouiller). Attention aussi aux axes qui seront ceux des premières variables citées (x1 et y1 ici).
PROC GPLOT DATA = ... ; PLOT y1*x1 y2*x2 / OVERLAY LEGEND = legend1 ; RUN ; QUIT ;
PROC PLOT DATA = tableSAS ; PLOT varY * varX = "#" $ variableTexte ; RUN ; QUIT ;Le signe # sert de marqueur aux points (il peut être remplacé par ce que l'on veut) et variableTexte contient les noms de modalités, identifiants d'individus, etc. A noter qu'à partir de la version 9.1 de SAS, ODS GRAPHICS produit le 1er plan factoriel d'une AFC avec la procédure CORRESP. En revanche, il nécessitera SAS/GRAPH en version 9.2 (et redevient dans SAS/Base à partir de SA 9.3 !!!).
Requêtage et manipulation de données
LIBNAME lib6 V6 "répertoire" ; LIBNAME lib8 V8 "répertoire" ; LIBNAME tout (lib6 lib8) ;Pour la conversion, sinon, après la définition de lib6 et lib8 comme ci-dessus, il est possible de transformer les tables d'une version à l'autre par une simple PROC COPY. Attention ! Il est certainement préférable de transformer une table v6 en table v8 que l'inverse (parfois impossible si un nom de variable dépasse 8 caractères, ou un label 32 signes, etc...).
DATA work.test ; INPUT variable1 & :$30. ; DATALINES ; Il fait beau Toto fait ses devoirs ; RUN ; DATA work.test ; SET work.test ; LENGTH debutsMots $ 10 ; numMot = 1 ; debutsMots = "" ; DO WHILE (SCAN(variable1,numMot) NE "") ; debutsMots=COMPRESS(debutsMots!!SUBSTR(SCAN(variable1,numMot),1,1)) ; numMot = numMot + 1 ; /* mot suivant */ END ; RUN ;
Nom_complet = TRIM(prenom)!!" "!!TRIM(nom) ;Ou, en SAS v9, utiliser la fonction STRIP (suppression des blancs à gauche et à droite), ou encore les fonctions CATT (concaténation et suppression des blancs à droite) ou CATX (concaténation, élimination des blancs à gauche et à droite, insertion d'un caractère séparateur) :
Nom_complet = CATX(" ", civilite, prenom, nom) ;
PROC SORT DATA = mesDonnees ; BY nom prenom adresse ; RUN ; DATA mesDonnees ; SET mesDonnees ; BY nom prenom adresse ; RETAIN identifiant 0 ; IF FIRST.adresse THEN identifiant = identifiant + 1 ; RUN ;
FILENAME test EMAIL TYPE = "TEXT/HTML" SUBJECT = "Ceci est un test" ; DATA _NULL_ ; INFILE CARDS DLM = "/" MISSOVER ; FILE test ; INPUT nom :$30. ; nom = UPCASE(nom) ; PUT "!EM_TO! " nom ; DETALINES; contact@od-datamining.com olivier decourt ; RUN ;
OUTPUT OUT = table PRED = variableP ;on a dans variableP les valeurs prédites pour les données inconnues (ce qu'on appelle un score). Ces valeurs s'échelonnent de 0 à 1, on les lit comme des probabilités d'occurrence d'un évènement. A partir de SAS 9.3, on peut aussi utiliser l'instruction SCORE.
- faire précéder le programme de l'option système VALIDVARNAME=ANY qui va autoriser les caractères accentués dans les noms.
- Faire un RENAME dès que possible pour se débarrasser de l'accent et pouvoir repositionner VALIDVARNAME à sa valeur initiale, V7.
OPTION VALIDVARNAME=ANY ; ODS OUTPUT crossTabFreqs = work.maSortie (RENAME = ("Fréquence"n = Frequence)) ; PROC FREQ DATA = ... ; TABLE ... ; RUN ; OPTION VALIDVARNAME=V7 ;
data ww.CMb; set ww.CM1b ww.CM2b ... ww.CM40b; run;Merci Bonjour, et merci de votre question. Vous pouvez utiliser un programme comme celui-ci :
%MACRO empilement (nbTables) ; DATA ww.CMb ; SET %DO i=1 %TO &nbTables ; ww.CM&i.b %END ; ; RUN ; %MEND empilement ;
%empilement (40)A partir de SAS 9.2, plus besoin de macros ! Vous pouvez écrire directement
SET ww.CM1-ww.CM40 ;dans votre étape Data. Par contre, comme dans votre cas le nom des tables ne se termine pas par un nombre, il faudra rester à la solution macro.
proc transpose data=infic prefix=cnt out=outfic; var nocnt; by client; run ;va générer cnt1 à cntn. Comment récupérer le nombre de variables générées (n) dans une étape data ? Merci. Pour mettre ce nombre dans une macro-variable, voici un premier programme :
DATA _NULL_ ; SET outfic ; ARRAY transpose cnt: ; CALL SYMPUT ("nbNllesVar", DIM(transpose)) ; STOP ; RUN ;Vous récupérez le nombre de variables créées par la procédure TRANSPOSE dans la macro-variable &nbNllesVar. Pour disposer de ce nombre sous forme de variable dans l'étape Data, il suffit de modifier légèrement ce programme :
DATA ... ; SET outfic ; ARRAY transpose cnt: ; nbVar = DIM(transpose) ; /* il est également possible d'opérer des traitements avec une boucle sur l'Array : DO i = 1 TO DIM(transpose) ; traitement sur transpose(i) END ; */ RUN ;
%LET recherche = ar ; PROC PRINT DATA = sashelp.class ; WHERE soc LIKE "%&recherche%" ; RUN ;Comment résoudre ce problème ? Il faut masquer au macro-compilateur les deux %. Pour cela, on utilisera la macro-fonction %NRQUOTE, qui masque des caractères pendant la phase de résolution (transformation du programme par le macro-compilateur)... Le macro-compilateur n'est donc intéressé que par l'expression &recherche, qui ne pose pas de problème. Il est ensuite transmis le programme correct au compilateur SAS, qui aura le droit de voir les %.
%LET recherche = ar ; PROC PRINT DATA = sashelp.class ; WHERE soc LIKE "%NRQUOTE(%)&recherche%NRQUOTE(%)" ; RUN ;
LIBNAME fichier6 V6 '/user/chemin/rep' ; LIBNAME fichier8 '/user/chemin/rep' ; PROC COPY IN = fichier6 OUT = fichier8 ; RUN ;Autre possibilité, vous pouvez télécharger gratuitement depuis Internet le SAS Viewer (il est aussi sur les CD d'installation, demandez aux informaticiens) qui devrait permettre d'ouvrir la table Unix et de l'enregistrer sous... soit directement le format SAS7BDAT Windows v8 - v9, soit au pire en fichier plat .CSV et vous devrez refaire un import puis remettre les labels.
%macro essai; data table; input variable; cards; 1 2 3 ; run; %mend essai; %essai; ERROR: The macro ESSAI generated CARDS (data lines) for the DATA step, which could cause incorrect results. The DATA step and the macro will stop executing. NOTE: The data set WORK.TABLE has 0 observations and 1 variables.Bonjour. Effectivement, l'emploi de CARDS, CARDS4 et DATALINES est interdit dans un macro-programme. La raison est sans doute la difficulté prévisible de bien repérer les données proposées. Une alternative sera de mettre les données dans un fichier texte et de le lire avec INFILE ... INPUT.
data _null_; infile "c:\essai.txt" firstobs=2 dlm =','; input a$ b$; run;Bonjour. CALL SYMPUT ne s'applique pas forcément à des tables SAS en dur ; tout ce qui peut être chargé dans le vecteur de travai (PDV) peut être utilisé dans un CALL SYMPUT pour alimenter des macro-variables.
data _null_; infile "c:\essai.txt" firstobs=2 dlm =','; input a$ b$; call symput ("mva",a) ; call symput ("mvb",b) ; run;Ce programme doit fonctionner correctement et vous créer les MV nécessaires.
dateSAS = DATEPART(dateSPSS + "15oct1582:00:00:00"dt) - 1 ; FORMAT dateSAS DDMMYY10. ;
LIBNAME maBase ORACLE USER="..." PASSWORD="..." PATH="..." ;ou bien
PROC SQL ; CONNECT TO ORACLE (USER="..." PASSWORD="..." PATH="...") ; SELECT * FROM CONNECTION TO ORACLE (requête Oracle) ; DISCONNECT FROM ORACLE ; QUIT ;Dans le premier cas, on accède aux données Oracle comme si c'était des tables SAS ; dans le second, on peut ajouter un CREATE TABLE dans la proc SQL pour récupérer en table SAS les données extraites par la requête.
- attention à ne pas confondre LENGTH et FORMAT ; le premier est le nombre d'octets sur lequel une valeur est stockée et le second une indication de la manière dont les valeurs sont affichées. Dans le cas d'une variable caractère, les deux sont souvent semblables : une variable stockée sur 3 octets s'affiche sur 3 caractères (LENGTH=$ 3 et FORMAT=$3.). Pour les variables numériques, on a un LENGTH de 8 (par défaut) et un affichage assez libre : BEST12. signifie juste que SAS utilisera au plus 12 caractères pour afficher la valeur. Le LENGTH de 8 est approprié si la variable contient des décimales. Sinon, selon son ordre de grandeur, on peut gagner de la place avec un LENGTH plus court, entre 3 et 7.
- la compression n'est pas un moyen de gagner du TEMPS mais de la PLACE. Je n'ai pas l'impression que ce soit votre but ; en effet, une table compressée (zippée en interne par SAS) nécessite plus de temps à s'ouvrir (il faut la décompresser) et à s'écrire (il faut la recompresser). Ce n'est donc pas forcément la solution espérée.
data format.fmtDRCourt; set tdbprod.BaseCourtiers (keep=gc DR rename=(gc=start dr=label)); by start; type="N"; /* N Numérique */ fmtname="DRCOURT"; run; proc format lib=format cntlin = format.fmtDRCourt /*fmtlib*/; run;
Je vous propose la variante suivante. DATA format.fmtDRCourt ; SET tdbprod.BaseCourtiers (KEEP = gc dr RENAME=(gc=start)) ; BY start ; LENGTH label $32 ; type="N" ; /* N Numérique */ fmtname="DRCOURT" ; IF _N_=1 THEN DO ; hlo = "O" ; /* ligne OTHER */ label = "Autres" ; OUTPUT ; END ; hlo = " " ; label = dr ; /* ou PUT(dr, format.) si DR est une variable numérique */ OUTPUT ; RUN ; PROC FORMAT LIB=format CNTLIN = format.fmtDRCourt FMTLIB ; RUN ;La variable HLO (High, Low, Other) permet de repérer les lignes "spéciales" dans le descriptif d'un format : celles qui utilisent un de ces trois mots-clés. La variable HLO vaut alors "L", "H" ou "O" selon les cas.
proc format; value anccrea low- mdy(12,31,2002) = "1- avant 01/2003" mdy(12,31,2002)-mdy(12,31,2004)= "2- entre 2003 et 2004 " mdy(12,31,2004)-high= "3- depuis 2005 " other ="???"; run;et ça
proc format; value anccrea low- '31/12/2002'd = "1- avant 01/2003" ...Merci. La 2e solution n'était pas bien loin du compte. Simplement, la forme de la date entre guillemets doit être JJ puis mois sur 3 lettres en anglais puis année. Comme dans un WHERE.
PROC FORMAT ; VALUE anccrea LOW- '31dec2002'd = "1- avant 01/2003" ... ; RUN ;
proc format; value $test '10' = 'l'arbre'; run;Comment faire comprendre à SAS qu'il ne s'agit pas de la fin du label ? Merci Bonjour. Le plus simple pour résoudre votre problème est tout simplement d'écrire votre libellé entre guillemets doubles. Il n'y aura alors pas de confusion avec les apostrophes. Dans SAS, les guillemets doubles et les apostrophes sont totalement équivalents, à condition qu'ils soient par paires identiques (= quand on ouvre des guillemets doubles, on ferme des guillemets doubles). La seule différence tient à un texte contenant une référence à une macro-variable &nomMV. Entre guillemets simples (apostrophes), la macro-variable ne sera pas résolue ; entre guillemets double, elle le sera.
proc format; value $test '10' = "l'arbre"; run;
- de filtrer les données en amont avec un WHERE
- d'utiliser un format pour associer les valeurs des valeurs des variables CLASS à ne pas afficher avec des valeurs manquantes (par défaut, la procédure Tabulate n'affiche pas les valeurs manquantes)
PROC TABULATE DATA = ... FORMAT = NUMX12.2 ;devrait faire l'affaire.
OPTION LOCALE = FRENCH ;par exemple en début de programme SAS, en dehors de toute procédure et étape Data.
proc format; value pop (multilabel) low-35="35 ans et moins" low-high/* ?? */="tout le monde"; run;mais si j'applique ce format dans une proc freq par exemple:
proc freq data=****; table age; format age pop.; run;j'obtiens bien les 35 ans et moins d'une part, mais dans "tout le monde" je n'ai que les plus de 35 ans. Comment obtenir l'ensemble de la population? Merci pour votre réponse Bonjour. Il n'est malheureusement pas possible d'utiliser les formats MULTILABEL partout. Seules les procédures MEANS et TABULATE les supportent. Une alternative pour votre problème : dupliquer les observations correspondant aux moins de 35 ans, avec une étape Data.
DATA work.pour_etude ; SET *** ; IF age < 35 THEN DO ; doublon = 1 ; OUTPUT ; END ; doublon = 0 ; /* pour tout le monde */ OUTPUT ; RUN ;Ensuite il suffit d'habiller la variable DOUBLON avec un format : 0 -> tout le monde 1 -> moins de 35 ans.
PROC FORMAT ; PICTURE milliers (ROUND) 0 - HIGH = "000 000 009" ; RUN ;Vous utilisez ensuite le format milliers. quand vous en avez besoin. Pour plus d'informations sur les formats "picture", voir Les pictures expliqués à ma fille.
- pour que les titres des instructions TITLE apparaissent en tête de chaque onglet; ajoutez l'option EMBEDDED_TITLES="YES" aux spécifications d'ODS TAGSETS.EXCELXP
- si vous souhaitez conserver un titre visible à l'impression, vous pouvez l'indiquer avec l'option PRINT_HEADER="ici titre personnalisé", toujours dans l'instruction ODS TAGSETS.EXCELXP.
ODS TAGSETS.EXCELXP FILE="c:\temp\titres.xls" OPTIONS(EMBEDDED_TITLES="YES" PRINT_HEADER="%NRSTR(&E)Tout le classeur porte sur la table SASHELP.CLASS" SHEET_NAME="Détail" SHEET_INTERVAL="PROC") ; TITLE1 "Liste des enfants" ; PROC PRINT DATA=sashelp.class NOOBS ; RUN ; ODS TAGSETS.EXCELXP OPTIONS(SHEET_NAME="Stats") ; TITLE1 "Statistiques" ; PROC FREQ DATA=sashelp.class ; TABLE sex age ; RUN ; TITLE ; ODS TAGSETS.EXCELXP CLOSE ;
ODS RTF FILE="c:\temp\test vertical.doc" ; PROC REPORT DATA=sashelp.shoes SPLIT=" " NOWD ; COLUMNS _ALL_ ; RUN ; ODS RTF CLOSE ;Ici l'espace sert d'indication pour revenir à la ligne, mais on peut modifier les labels pour incruster à l'endroit voulu (y compris après chaque lettre !) un caractère de retour à la ligne.
PROC CONTENTS DATA=sashelp.shoes OUT=work.labels (KEEP=name label) NOPRINT ; RUN ; DATA _NULL_ ; SET work.labels END=fin ; LENGTH newLabel $ 200 ; newLabel = PRXCHANGE("s/(.)/¤$1/",-1,STRIP(COALESCEC(label,name))) ; newLabel = SUBSTR(newLabel,2) ; /* élimine le 1er ¤ ajouté en tête */ IF _N_=1 THEN CALL EXECUTE ("DATA work.export ; SET sashelp.shoes ; LABEL ") ; CALL EXECUTE (name !! "=" !! QUOTE(STRIP(newLabel))) ; IF fin THEN CALL EXECUTE ("; RUN ;") ; RUN ; ODS RTF FILE="c:\temp\test vertical.doc" ; PROC REPORT DATA=work.export SPLIT="¤" NOWD ; COLUMNS _ALL_ ; RUN ; ODS RTF CLOSE ;
/* pour un classeur Excel : */ PROC EXPORT DATA = votreTable OUTFILE = "chemin et nom du fichier créé" DMBS = EXCEL ; RUN ; /* pour un fichier texte à séparateur tabulation */ PROC EXPORT DATA = votreTable OUTFILE = "chemin et nom du fichier créé" DMBS = DLM ; DELIMITER = "09"x ; RUN ;
proc template; define style styles.noborder; parent=styles.minimal; style Pays / just = center; end; run; ODS HTML FILE='Edition.xls' STYLE=styles.noborder; title; Proc print data=final noobs; Run; ods HTML close ;Merci d'avance. Je vous conseillerais d'aller agir directement dans la procédure Print, qui le permet, plutôt que dans la procédure Template, qui accepte mal les cas particuliers de mise en forme par colonne.
ODS HTML FILE='Edition.xls' STYLE=minimal ; TITLE ; PROC PRINT DATA=final NOOBS ; VAR entite ; VAR pays / STYLE = [JUST=CENTER] ; VAR ; RUN ; ODS HTML CLOSE ;Attention cependant, selon les versions, Excel n'applique pas toujours les consignes de centrage. Si vous possédez SAS 9 et Excel 2003, je vous conseille plutôt de passer par la destination ODS TAGSETS.EXCELXP que par ODS HTML.
ODS ODS TAGSETS.EXCELXP FILE='Edition.xls' STYLE=minimal ; title; Proc print data=final noobs; VAR entite ; VAR pays / STYLE = [JUST=CENTER] ; VAR ; Run; ods ODS TAGSETS.EXCELXP close ;
- soit la création de classeurs au format XML si tu as Excel 2003 ou plus récent pour les relire (il y a des macros en ce sens sur Internet, par exemple sur le site de Richard deVenezia) ;
- soit avec SAS PC et un lien DDE (écriture "en live" vers une feuille Excel déjà ouverte)
- pour toutes versions de SAS depuis la 8.0, vous pouvez ouvrir une destination ODS HTML sur le même principe qu'ODS RTF, en indiquant dans FILE= un fichier dont l'extension est .XLS. Vous ne créerez pas une feuille Excel au sens strict, mais une page Web qu'Excel sait lire à partir de la version 1997
- pour SAS 9.1 et Excel 2003 minimum, vous pouvez utiliser ODS TAGSETS.EXCELXP qui va créer un (presque) véritable classeur Excel. La documentation sur cette destination et ses options peut s'afficher dans la fenêtre Log en exécutant le programme suivant :
ODS TAGSETS.EXCELXP OPTIONS(DOC="help") FILE = "c:\temp\rien.xls" ;
- pour SAS 9.4 et Excel 2007 minimum, vous pouvez utiliser ODS EXCEL qui va créer un véritable classeur Excel d'extension XLSX.
filename sortie DDE "excel|Feuil1!l1c2:l1c79" notab; DATA _null_; SET pgm; FILE sortie; PUT COL1 '09'x COL2 '09'x COL3 '09'x COL4 '09'x COL5 '09'x COL6 '09'x COL7 '09'x COL8 '09'x COL9 '09'x COL10 '09'x COL11 '09'x COL12 '09'x COL13 '09'x COL14 '09'x COL15 '09'x COL16 '09'x COL17 '09'x COL18 '09'x COL19 '09'x COL20 '09'x COL21 '09'x COL22 '09'x COL23 '09'x COL24 '09'x COL25 '09'x COL26 '09'x COL27 '09'x COL28 '09'x COL29 '09'x COL30 '09'x COL31 '09'x COL32 '09'x COL33 '09'x COL34 '09'x COL35 '09'x COL36 '09'x COL37 '09'x COL38 '09'x COL39 '09'x COL40 '09'x COL41 '09'x COL42 '09'x COL43 '09'x COL44 '09'x COL45 '09'x COL46 '09'x COL47 '09'x COL48 '09'x COL49 '09'x COL50 '09'x COL51 '09'x COL52 '09'x COL53 '09'x COL54 '09'x COL55 '09'x COL56 '09'x COL57 '09'x COL58 '09'x COL59 '09'x COL60 '09'x COL61 '09'x COL62 '09'x COL63 '09'x COL64 '09'x COL65 '09'x COL66 '09'x COL67 '09'x COL68 '09'x COL69 '09'x COL70 '09'x COL71 '09'x COL72 '09'x COL73 '09'x COL74 '09'x COL75 '09'x COL76 '09'x COL77 '09'x COL78 '09'x; RUN;Or, sur ma feuille Excel, seules les 22 premières variables sont inscrites. Si je diminue le format de mes variables au minimum (format 3.2), j’arrive à obtenir les 64 premières variables. Mais j’ai toujours une perte d’informations… Comment puis-je faire ? Le problème vient de la largeur du "tuyau" utilisé par SAS pour envoyer les infos à Excel ; par défaut, il ne fait que 256 octets, ce qui ne permet pas de véhiculer les valeurs de vos 78 variables. On peut augmenter cette largeur de tuyau avec l'option LRECL (Logical RECord Length) dans l'instruction FILE.
... FILE sortie LRECL = 4000 ; ...Le reste de votre programme, lui, n'a pas à changer.
ODS HTML FILE = "chemin et nom de votre fichier.xls" ; TITLE ; FOOTNOTE ; PROC PRINT DATA = votre_table LABEL NOOBS ; RUN ; ODS HTML CLOSE ;Vous obtiendrez ainsi une pseudo feuille Excel (en fait, c'est une page Web habillée d'une extension XLS, mais Excel 97 n'y verra que du feu). En revanche, pour pouvoir ajouter d'autres feuilles au classeur par la suite, il est recommandé d'ouvrir Excel, d'ouvrir la feuille créée et de la sauvegarder en forçant son type à "Classeur Excel". Plus proprement, mais uniquement si vous possédez le module ACCESS TO PC FILES, vous pouvez exporter directement dans une vraie feuille Excel ainsi :
PROC EXPORT DATA = votre_table OUTFILE = "chemin et nom de votre fichier.xls" REPLACE DBMS = EXCEL97 ; RUN ;Pour savoir si vous possédez ledit module, exécutez le programme suivant :
PROC SETINIT NOALIAS ; RUN ;et regardez dans la Log. Si une ligne "SAS/ACCESS Interface to PC Files" y apparaît (ou un intitulé approchant, il varie selon les versions), c'est bon. Sinon, il faudra opter pour la première solution.
ods rtf body = "c:\temp\essai.doc" ; proc print data = grosse.table ; run ; ods rtf close ; options noxwait ; x "start winword" ; DATA _null_ ; BIDON = sleep(10) ; /* attente de l'ouverture de Word */ RUN ; filename word DDE "winword|system" ; DATA _null_ ; FILE word ; PUT '[FileOpen .name="C:\temp\essai.doc"]' ; /* ouverture du document Word */ PUT '[FileSaveAs .Name="essai.htm" .Format=wdFormatHTML]' ; /* enregistrement au format HTML */ PUT '[FileExit 1]' ; /* fermeture de Word */ RUN ;
- remplacer tous les points du tableau par des virgules sous Excel (avec un Remplacer)
- changer le séparateur décimal (Menu Démarrer de Windows, Panneau de Configuration, Paramètres Régionaux, onglet Nombres) de la virgule pour le point.
- si le tableau est généré par une PROC TABULATE, rajouter à l'instruction TABLE qu'il faut employer des formats NUMXx.y, qui fonctionnent comme les formats numériques x.y habituels, mais affichent une virgule comme séparateur décimal ! Pour cela, la commande à insérer est *format=NUMX12.2 par exemple.
- si le tableau est généré par une PROC PRINT, une PROC TABULATE ou une PROC REPORT, utiliser les instructions de formatage avec l'attribut de style TAGATTR qui permet d'envoyer à Excel des indications de format de cellule (cf. L'export de SAS vers Excel expliqué à ma fille)
Est-ce normal que pour 100 000 lignes, SEM indique le message d'erreur suivant : out of resources ?
Il ne faut pas trop charger SEM dans une configuration avec un serveur qui n'a pas une grosse capacité. Le mieux, c'est de le faire monter en charge progressivement, pour voir où il casse. Dans l'absolu, je ne peux pas dire "100000 c'est trop" ou "100000 ça devrait passer". D'une fois sur l'autre, je n'ai pas les mêmes résultats sur mon propre PC.
Il faut savoir cependant que SEM demande surtout deux choses : de l'espace disque pour entreposer ses multiples tables temporaires (il faut donc choisir de domicilier son projet dans un endroit où la place libre ne manque pas et où il n'existe pas de quotas) et surtout, pour l'exécution des tâches, de la mémoire vive. Mieux vaut donc une machine (serveur ou PC en "stand-alone", c'est à dire sans faire de client/serveur) avec beaucoup de mémoire vive (ajouter des barettes, fermer les autres applications, etc...) qu'avec un ou plusieurs processeurs très rapides, car la puissance de calcul passe après (il lui faut en tout premier lieu de la place) ; de plus, avant la version 9.0, SAS (et a fortiori SEM) ne sait pas profiter d'un multi-processeur.
Je voudrais faire une régression logistique en utilisant des classes de mes variables quantitatives... Pour cela je peux utiliser le noeud transform variables et calculer des classes selon les quartiles ou quelque chose du genre mais le problème c'est que j'aimerais faire une classe exclusivement = 0 ... car pour les montants par exemple il y en beaucoup qui sont égaux à zéro. Donc je voudrais avoir ma 1ère classe seulement pour des valeurs nulles puis la 2ème par exemple pour des valeurs comprises entre zéro exclus et 12000 F... Comment m'y prendre ?
Pour le problème de découpage en classes : voici une solution à la main, parce qu'on ne peut pas faire mieux sans passer par un macro-programme dans le noeud SAS Code pour le faire automatiquement :
- calculer les valeurs des quantiles. Les noter sur un bout de papier (c'est VRAIMENT une solution à la main !)
- dans Transform Variables, créer une nouvelle variable, dont la définition sera : 1+(VAR>0)+(VAR>12000)+(VAR>20000) par exemple. Remplacer VAR par le nom de la variable quali de départ, et 12000 et 20000 par les quantiles de la feuille de papier.
Les tests entre parenthèses renvoient des booléens : 0 pour faux, 1 pour vrai. SEM produit une variable qui vaut : 1 pour les valeurs nulles, 2 pour les valeurs entre 0 exclus et 12000 inclus, 3 pour les valeurs entre 12000 exclus et 20000 inclus, 4 pour les valeurs > 20000.
Bonjour, pouvez -vous me donner les caractéristiques et les différences entre les logiciels Sas Guide et Sas Entreprise Miner? Peut on faire des scores avec Sas Guide?
Merci beaucoup pour votre réponse.
SAS Enterprise Guide est un logiciel qui génère du code SAS à travers une interface presse-bouton. Il est orienté vers la construction de requêtes (extraction de données, jointures) et la statistique plutôt descriptive (graphiques, stats exploratoires). Il possède des interfaces pour la construction de modèles (régression linéaire, logistique, données de survie) mais pour la construction d'un score, les options ne sont pas très nombreuses. On en vient alors à écrire soi-même le code, en utilisant les procédures Logistic et Discrim disponibles dans le module SAS/STAT. Les graphiques et autres informations complémentaires doivent également être obtenues à la main.
En comparaison, SAS Enterprise Miner est non seulement une interface, mais intègre également des fonctionnalités spécifiques pour le Data Mining, en particulier la construction d'arbres de décision (proc Arboretum), de réseaux de neurones (proc Dmneurl), et même une procédure de régression spécifique (proc Dmreg). A part l'analyse discriminante, toutes les techniques sont directement accessibles dans l'interface de Miner. Les graphiques commentant les résultats sont spontanément construits par le logiciel, de même que les mises en concurrence de méthodes (comparaison de courbes de lift par exemple). SAS Enterprise Miner propose en outre une méthodologie de projet Data Mining, et des fonctionnalités d'échantillonnage, de gestion des valeurs manquantes, de traitement des valeurs extrêmes, de segmentation, etc. qui lui sont entièrement spécifiques.
En résumé : SEG est une surcouche au logiciel SAS permettant de générer des programmes, avec une vocation plutôt généraliste. On peut s'en servir pour construire un score, avec les outils (procédures) usuels de SAS/STAT. SEM est un outil entièrement tourné vers la construction de scores et n'a pas la vocation "tous publics" de Guide.
Bonjour, J'essaye d'utiliser la fonction week dans mon programme, pour convertir une date en découpage hebdo. Il semble que cette fonction ne soit pas reconnue. Je suis actuellement en SAS V8, est-ce que cette fonction n'est dispo qu'en V9 ? Je vous remercie pour vos réponses. Bonne journée !
Bonjour. Effectivement la fonction WEEK est nouvelle avec la version 9. A l'utilisation, elle nécessite un 2e argument, "V" ou "W" pour indiquer le mode de calcul des numéros de semaine. Les semaines commencent le lundi et la semaine n°1 commence au 1er lundi de janvier. Les jours précédant le 1er lundi de janvier appartiennent à la semaine 52 si on indique "V", ou la semaine 0 avec "W".
En version 8, vous devez utiliser la fonction INTCK qui calcule le nombre de lundis entre 2 dates (WEEK.2 désigne des semaines commençant le lundi) : semaine=INTCK("WEEK.2", MDY(1,1,YEAR(maDate)), maDate) ; Avec cette formule, les jours précédant le 1er lundi de janvier appartiendront à la semaine 0.Bonjour, je dispose d'une table avec des dates sous un certain format. je voudrais savoir comment les afficher via une proc freq sans format, c'est-à-dire en les visualisant sous la forme du nombre de jour depuis le 1er JAN 1960. L'objectif étant de récupérer les dates distinctes de ma table dans une liste, et de boucler dessus. Par avance, merci.
Bonjour.
Pour répondre directement à votre question, ajoutez une instruction FORMAT maVariableDate 6. ; à votre procédure FREQ. Sinon, vous pouvez directement créer une table de dates distinctes avec une procédure SORT avec l'option NODUPKEY, sans avoir besoin de la proc FREQ.
Bonjour. J'ai une date de format $10. (style 10/10/2010) que je voudrais transformer en date DDMMYY10. Merci d'avance de votre réponse.
Bonjour.
Il faudra créer une nouvelle variable, de type numérique ; pour cela, en SQL ou dans une étape Data, la formule sera INPUT(variableExistante, DDMMYY10.) et le résultat sera en nombre de jours depuis le 01/01/1960. Restera ensuite à l'habiller du format date de votre choix.
Bonjour,
j'ai une variable date dans un fichier, et je souhaite faire la répartition en fonction de tranche gérées par un format que je crée... et je n'arrive pas à créer ce format (sans passer par le calcul du nombre de jours correspondants à ma date..)
j'ai essayé ça :
proc format; value anccrea low- mdy(12,31,2002) = "1- avant 01/2003" mdy(12,31,2002)-mdy(12,31,2004)= "2- entre 2003 et 2004 " mdy(12,31,2004)-high= "3- depuis 2005 " other ="???"; run;et ça
proc format; value anccrea low- '31/12/2002'd = "1- avant 01/2003" ...
Merci.
La 2e solution n'était pas bien loin du compte. Simplement, la forme de la date entre guillemets doit être JJ puis mois sur 3 lettres en anglais puis année. Comme dans un WHERE.
PROC FORMAT ; VALUE anccrea LOW- '31dec2002'd = "1- avant 01/2003" ... ; RUN ;
Bonjour.
J'aurais souhaité afficher une date sous la forme suivante : Janvier 2005 (en français, mais sans le numéro du jour).
D'avance merci.
Bonjour.
Si vos données sont sous forme de dates SAS, vous pouvez utiliser :
- les formats "français" de dates de SAS, comme FRADFWDX. qui afficherait 01 janvier 2005 ;
- un format de type particulier, appelé PICTURE, créé par la procédure FORMAT. Dans le cas de votre demande, c'est ce qu'il convient d'utiliser :
PROC FORMAT ; PICTURE testDate LOW - HIGH = '%B %Y' (DATATYPE = DATE) ; RUN ;
Dans cette syntaxe, l'option DATATYPE = DATE permet de spécifier le type de données lues. On peut également avoir deux autres valeurs, TIME et DATETIME.
Les éléments %Y, %B qui composent la valeur affichée sont des mots-clés reconnus de la procédure FORMAT. Les principaux éléments sont :
- %a = jour de la semaine en français sur 3 lettres
- %A = jour de la semaine en français
- %b = mois sur 3 lettres en français
- %B = mois en français
- %d = jour du mois sans zéro initial
- %0d = jour du mois sur deux chiffres
- %j = jour de l'année (de 1 à 366)
- %m = mois (1 à 12) sans zéro initial
- %0m = mois sur deux chiffres
- %0y = année sur deux chiffres
- %Y = année sur quatre chiffres
Enfin, il est recommandé d'employer des apostrophes et non des guillemets autour de la valeur formatée afin d'éviter toute intervention du compilateur macro.
Comment positionner des lignes concernant le même identifiant les unes à la suite des autres ? Par ex:
identifiant | nom | prenom | date naissance |
111 | durand | paul | 01/10/1987 |
111 | durand | guy | 26/01/1999 |
111 | durand | pierre | 13/09/2001 |
333 | dupont | jack | 16/12/2004 |
Le problème est de positionner la famille durand , identifiant 111, sur la même ligne. Je vous remercie.
Bonjour, et merci de votre question.
Ce genre de "pivotage" de données n'est pas simple, et SAS ne fait pas grand-chose pour nous y aider. Il faut utiliser la procédure TRANSPOSE, sur chacune des variables à pivoter (ici, PRENOM et DATE DE NAISSANCE. On obtient plusieurs tables que l'on combinera dans une étape Data, avec plusieurs instructions SET. Le programme suivant résume les manipulations à effectuer...
DATA work.test ; INPUT id nom $ prenom $ dtnais DDMMYY10. groupe_sanguin $ ; CARDS ; 111 durand paul 01/10/1987 AB 111 durand guy 26/01/1999 A 111 durand pierre 13/09/2001 A 111 durand karl 14/10/2002 O 111 durand marie 14/10/2002 A 111 durand ulysse 25/01/2004 B 111 durand éléonore 25/01/2004 A 111 durand garance 25/01/2004 B 111 durand télémaque 25/01/2004 AB 111 durand vanessa 07/09/2005 A 111 durand armelle 07/09/2005 O 333 dupont jack 16/12/2004 AB ; RUN ; PROC SORT DATA = work.test ; BY id nom ; RUN ; PROC TRANSPOSE DATA = work.test OUT = work.res1 (DROP = _NAME_) PREFIX = prenom ; BY id nom ; VAR prenom ; RUN ; PROC TRANSPOSE DATA = work.test OUT = work.res2 (DROP = _NAME_) PREFIX = dtnais ; BY id nom ; VAR dtnais ; FORMAT dtnais DDMMYY10. ; RUN ; PROC TRANSPOSE DATA = work.test OUT = work.res3 (DROP = _NAME_) PREFIX = gpe_sanguin ; BY id nom ; VAR groupe_sanguin ; RUN ; DATA work.fus ; SET work.res1 ; SET work.res2 ; SET work.res3 ; BY id nom ; RUN ;
Je tiens à remercier Bernard Gestin de m'avoir soufflé cette solution plus simple que celle que j'avais proposée initialement.
Bonjour.
Dans une table SAS que j'ai récupérée, j'ai une variable qui contient manifestement une date, qui semble numérique sur une longueur de 8, mais elle a un aspect bizarre. Une valeur, par exemple, est : 14JUN1977:00:00:00. Les fonctions dates habituelles (YEAR, INTNX, etc.) me renvoient des résultats aberrants quand je les applique à cette variable. Que faire ?
D'avance merci.
Vous êtes en présence d'une variable de "type" Datetime (stockée en nombre de secondes depuis le 01/01/1960 à minuit). C'est donc bien du numérique sur 8 octets (8 octets ça permet de stocker des entiers énormes). Mais ce n'est pas une DATE au sens où les fonctions comme YEAR s'y attendent, c'est à dire un nombre de jours depuis le 01/01/1960. Quant à son aspect "bizarre", il s'explique par un format DATETIME. spécialement conçu pour ce type d'information.
La fonction DATEPART permet d'extraire la partie "date" d'un Datetime. Mais il faut bien penser à affecter un format date (DDMMYY10. par exemple) à la variable ainsi créée.
Une étape Data comme celle-ci résoud le problème :
DATA ma_nouvelle_table ; SET mon_ancienne_table ; variable_date = DATEPART(variable_datetime) ; FORMAT variable_date DDMMYY10. ; RUN ;
(Il convient bien sûr de changer les noms des tables et des variables pour coller à votre sujet.)
Bonjour, J’ai enregistré l'ensemble des commandes de mon batch dans un fichier txt. Quelles sont ensuite les commandes de lancement? D'avance merci
Bonjour.
Pour lancer un programme SAS en batch, la commande Unix correspond au raccourci qui lance habituellement SAS.
Il faut indiquer le programme à exécuter après l'option -SYSIN, entre guillemets.
Par exemple : "home/pgm/SAS9/sas.exe" -CONFIG "home/pgm/SAS9/SASV9.CFG" -SYSIN "home/users/perso/pgm.txt"
On peut récupérer la Log en indiquant un nom de fichier après l'option -LOG, et on doit indiquer des instructions ODS dans le programme à exécuter pour récupérer aisément les sorties. Si vous utilisez habituellement un autoexec, il est préférable d'indiquer celui-ci au début du programme à exécuter : par exemple :
%INCLUDE "home/users/perso/autoexec.sas" ; /* début du programme soumis en batch... */ DATA work.test ; SET etc.
Bonjour,
je travaille sur serveur et souhaiterais enregistrer mes tables sur le serveur sous un autre format que le format SAS (pour importation sous BO designer par la suite). Merci d'avance.
Bonjour.
Pour l'export vers Business Objects, le type de fichier le plus simple à transmettre depuis SAS est un fichier texte à séparateur tabulation. On peut le produire, avec une version 8 ou supérieure, à l'aide de la procédure EXPORT, comme le titre de votre question le suggérait :
PROC EXPORT DATA = sashelp.class OUTFILE = "~/test.dat" DBMS = TAB ; RUN ;
Le répertoire ~ est la racine de votre compte utilisateur.
L'autre option est d'utiliser un peu de macro-langage et au final une étape Data pour réaliser cet export. Le macro-langage récupère auprès du dictionnaire des données (créé par la PROC CONTENTS) une liste de noms de variable pour l'en-tête du fichier, et une liste de noms de variables pour l'export proprement dit. Ces créations de macro-variables se font dans une procédure SQL. Enfin, une étape Data d'export "classique" avec instructions SET, FILE et PUT, permet d'écrire dans le fichier voulu.
PROC CONTENTS DATA = sashelp.class OUT = work.dico NOPRINT ; RUN ; PROC SQL NOPRINT ; SELECT QUOTE(LEFT(TRIM(name))), LEFT(TRIM(name)) INTO : liste_en_tete SEPARATED BY " '09'x ", liste_variables SEPARATED BY " '09'x " FROM work.dico ORDER BY varnum ; QUIT ; DATA _NULL_ ; SET sashelp.class ; FILE "c:\test.dat" ; IF _N_ = 1 THEN PUT &liste_en_tete ; PUT &liste_variables ; RUN ;
Le charme de ces deux programmes est qu'ils ne nécessitent jamais l'énumération des noms des variables (pratique quand on possède des dizaines ou des centaines de colonnes dans la table à exporter).
Je souhaite allouer une librairie qui pointerait sur des données situées sur un serveur UNIX qui n'est pas celui sur lequel est installé le SAS que j'utilise.Cependant, si cela est utile, le logiciel SAS est installé sur les 2 serveurs.
Y-a-t-il une (ou plusieurs ??) solutions ?
Merci d'avance,
La présence de SAS sur le second serveur évite la solution assez brutale de devoir transférer (via FTP par exemple, ou un FILENAME FTP au mieux) les données d'un serveur à l'autre.
Deux solutions se profilent à ce problème :
- Faire travailler directement le second serveur, celui où se trouvent les données. Un RSUBMIT ... ENDRSUBMIT permet de lui faire effectuer le maximum de traitement. Pour rappatrier ensuite les données obtenues (si le but est de les exploiter sur le "premier" serveur), une procédure DOWNLOAD fera l'affaire. (Les syntaxes sont précisées en fin de réponse.
- La deuxième (et certainement pas dernière) solution consiste à déclarer sur le "premier" serveur une bibliothèque RLS, c'est à dire une image, un pointeur, un lien vers une bibliothèque du second serveur. On considère alors les données de cette bibliothèque comme toutes celles qui se trouvent sur le premier serveur. Les temps de réponse de cette solution seront certainement médiocres. Mais sa simplicité est maximale.
Syntaxe pour le RSUBMIT : RSUBMIT ; PROC xxx ... ; ... RUN ; ENDRSUBMIT ;
Syntaxe pour la proc DOWNLOAD : RSUBMIT ; PROC DOWNLOAD DATA = tableSASserveur2 OUT = tableSASserveur1 ; RUN ; ENDRSUBMIT ;
Syntaxe pour le RLS : RSUBMIT ; LIBNAME toto "chemin" ; ENDRSUBMIT ; LIBNAME Rtoto SLIBREF = toto SERVER = nomDuServeur ;
La démarche suivante pose problème :
- j'ai créé un échantillon sur ma session Unix...
- je l'ai transféré en tant que fichier à plat sur Windows NT
- je l'ai importé sous SEM...
le problème qui se pose : des variables qui étaient dans ma base de départ de type char deviennent de type num... j'ai voulu les modifier dans un noeud IDS mais ça ne fonctionne pas... Y a t-il un autre moyen?
Il s'agit en fait d'un problème d'importation de SAS lui-même, pas spécifique à SEM. Il prend comme numériques toutes les variables n'ayant que des valeurs chiffrées (même s'il s'agit de codes). Le plus simple est peut-être de faire l'import à la main avec une étape Data et une instruction INPUT.
Je travaille en client/serveur. Je crée en RSUBMIT des formats avec une PROC FORMAT. Je fais une option FMTSEARCH sur la librairie qui contient le catalogue de formats. Pour l'exécution de procédures, tout va bien. Mais quand je veux regarder ma table avec l'Explorer, SAS me dit qu'il ne trouve pas les formats. Que se passe-t-il ?
LE PROBLEME : l'architecture client/serveur ne fait pas transiter les formats. Cela implique entre autres qu'on ne peut pas utiliser sur le client les formats du serveur et vice-versa, et que l'on ne peut pas créer sur le serveur des formats depuis le poste client (même dans un RSUBMIT).
LA SOLUTION : Première étape, créer le(s) format(s) en LOCAL. Donc sur le PC. Pour cela, exécuter EN-DEHORS du bloc RSUBMIT / ENDRSUBMIT la procédure formats avec une syntaxe
PROC FORMAT LIB = librairie_locale ; etc... RUN ;
Deuxième étape, le catalogue FORMATS créé dans la librairie locale doit être "remonté" sur le serveur. Pour cela, SUR LE SERVEUR cette fois (dans un bloc RSUBMIT / ENDRSUBMIT), utiliser la PROC UPLOAD qui est dédiée à la copie de "membres" SAS d'une librairie client dans une librairie distante du serveur. Si, par exemple, vous avez stocké les formats dans WORK.FORMATS, vous les remonterez ainsi vers ServLib.FORMATS :
PROC UPLOAD INCAT = WORK.FORMATS OUTCAT = ServLib.FORMATS ; RUN ;
Je voudrais savoir dans mon étude si dans le temps il y a un effet de propagation de différents types d'incidents (3 types).
Pour cela j'ai utilisé le noeud "Association" de SEM en mettant la variable temps (date + heure) comme variable séquentielle, la variable type d'incidents comme variable cible et en cochant l'option "sequence". Pouvez-vous m'indiquer ce que fait SAS derrière : est-ce qu'il discrétise la variable temps? Si oui, comment? Quel est le pas de temps (date/ heure / minute...)? Peut-on avoir la main dessus? (ex : choisir le pas de temps heure pour une même date)
Merci d'avance.
Le noeud Association n'utilise la variable séquentielle qu'en tant que numéro d'ordre. Il ne fait donc pas la différence entre une variable numérotée 1,2,3 et une variable temps. Les écarts ne sont pas non plus pris en compte : 1,2,4 est une séquence analogue à 1,2,3.
Le seul moyen de prendre en compte les écarts serait de les inclure en tant qu'items virtuels, sous forme d'intervalle de temps par exemple :
- Achat 1 : lit
- Achat 1 : 1er achat [item virtuel]
- Achat 2 : canapé
- Achat 2 : entre 1 et 3 mois après le 1er achat [item virtuel] Achat 3 : cuisine équipée
- Achat 3 : un an après le 1er achat [item virtuel] Achat 3 : plus de six mois après l'achat précédent [item virtuel] ...
De manière à ce que ces écarts puissent apparaître dans les règles.
Bonjour,
J'aimerais effectuer un arbre de régression, à savoir un arbre avec une cible quantitative. Cela est-il possible avec Sas EM? Et si oui, comment? Les arbres de décisions sont-ils possibles avec Sas Guide ou Sas Base? Merci pour votre aide.
Oui, il est possible d'utiliser SAS EM pour construire des arbres de régression. Pour cela, il suffit de déclarer comme variable cible une variable quantitative (type = INTERVAL) dans le nœud INPUT DATA SOURCE. Ensuite, SEM propose dans le nœud TREE deux types d'arbres : celui dérivé de CART qui choisit les coupures sur une réduction de la variance intra-nœuds, et celui dérivé de CHAID qui choisit les coupures avec un test de Fisher (F test).
La procédure mise en œuvre est la proc ARBORETUM (dans SAS 9) ou la proc DMSPLIT (dans SAS v8). Ces procédures ne sont disponibles qu'avec une licence SAS EM. Donc on ne peut pas les utiliser avec seulement une licence SAS Base ou SAS/STAT. Cependant, ces procédures ont une syntaxe (certes non documentée) donc peuvent être incluses dans des programmes et des macros qu'on exécutera directement depuis SAS PC ou SAS Enterprise Guide.
Bonjour, je suis en stage et je voudrais réaliser un arbre de décision sous SAS. Je voudrais connaître la forme du programme permettant de construire un arbre de décision sous SAS. Merci d'avance
Il n'existe malheureusement pas de programme existant directement dans SAS pour réaliser des arbres de décision. Ceux-ci peuvent être produits avec l'interface SAS Enterprise Miner, qui fait l'objet d'un module facturé en sus.
A partir de SAS 9.4, on peut cependant produire des arbres de décision avec la procédure HPSPLIT de SAS/STAT.
Probleme de discrimination :
Input : n individus sur lesquels sont mesurés p variables numériques. Output : la variable binaire d'intéret. Structure des données : seulement 20% des individus posseèdent la caractéristique binaire. Modele : par exemple un reseau de neurones de type perceptron multicouche.
Question : les individus présentant la valeur 1 (dans 20% des cas) apparaissent naturellement sous représentés dans le jeu de données. Par conséquent, le modèle estimé s'adapte très pauvrement : il prédit dans la grande majorité des cas une valeur = à 0. Quelles sont les techniques existantes pour sur-pondérer la sous population présentant la valeur 1 de la variable binaire d'intéret. La seule que je connaisse etant :répliquer plusieurs fois cette meme sous population, ou utiliser des methodes de type arcing.
Merci d'avance pour la réponse apportée.
La duplication d'individus est toujours dangereuse, sauf quand elle est contrôlée par un mécanisme de type bootstrap, comme dans les méthodes d'arcing.
N'est-il pas préférable de travailler sur un échantillon équilibré (50% de 0, 50% de 1) quitte à réduire la taille de votre échantillon de travail ?
L'emploi d'un arcing (boosting ou bagging) sur ce genre de population donne en général de bons résultats (plus spectaculaires si vous partez d'un modèle moins stable qu'un réseau de neurones, par exemple un arbre de décision).
Généralement (sauf dans le noeud "Arbre de Décision"), les observations comportant au moins une valeur manquante sont exclues de l'analyse. On peut choisir de les compléter au préalable avec le noeud Replacement, ou avec un noeud SAS Code faisant appel à la PROC MI. Dans le noeud Arbre de Décision, on peut utiliser la valeur manquante comme une valeur à part entière, ou exclure les observations incomplètes comme dans les autres modèles. Pour cela, dans l'onglet BASIC, on coche (ou pas) TREAT MISSING AS AN ACCEPTABLE VALUE.
Dans SEM, les valeurs manquantes ne sont pas traitées, sauf cas exceptionnel, comme des valeurs ordinaires. Tous les codages de la variable cible sont autorisés, sauf ceux qui incluent une valeur manquante.
Bonjour, Voilà mon souci : je voudrais faire une Classification sur une énorme base (env 2 millions de lignes). Ce sont des données qualitatives, alors je dois passer par une ACM, donc construire un Tableau Disjonctif Complet (en tout j'ai 3 variables et 11*97*18 modalités). Seulement SAS bloque un peu beaucoup (il a mouliné toute la nuit et n'a pas avancé...)! La proc transreg que vous proposez dans cette FAQ n'est-elle pas appropriée ici? Ma base est-elle trop volumineuse pour un tel traitement? Si oui, comment faire ma classification? Merci beaucoup pour votre éclairage!
Deux pistes à explorer pour que votre traitement puisse se faire dans un temps acceptable (et, vu vos volumes, se faire tout court !).
1) travailler uniquement sur un échantillon : au lieu des 2 millions de lignes, vous pourriez construire une typologie sur seulement 10% d'entre eux, et ensuite chercher les règles de construction des classes (par un modèle statistique, ou plus simplement par une caractérisation univariée) pour dispatcher l'ensemble de vos lignes dans les différentes classes. 2) réduire le nombre de modalités d'une de vos valeurs : 97 valeurs me paraît un nombre un peu excessif. D'autant que cela risque de déséquilibrer fortement l'ACM (les premiers axes se concentreront sur l'information contenue dans cette variable et pas dans les 2 autres) Vous pourriez faire un recodage pour vous ramener à une vingtaine de valeurs ; non seulement ça équilibre l'ACM, mais en plus la taille des fichiers à traiter (tableau disjonctif complet en entrée de la procédure Corresp, et le tableau de Burt qu'elle construit en interne) sera plus raisonnable. Comment faire votre recodage ? Déjà sur des critères métier, je pense. Et également en faisant une ACM sur cette variable uniquement, dans l'espace des variables seulement, de préférence sur un échantillon aléatoire de vos deux millions de lignes. Pour cette ACM préalable, la syntaxe SAS est la suivante :PROC CORRESP DATA = votreTableSAS MCA SHORT ; TABLES votreVariableA97Modalites ; RUN ;
Si vous avez une version 9 de SAS, vous pouvez ajouter les deux instructions suivantes avant la procédure correspondante :
ODS GRAPHICS ON ; ODS HTML FILE = "c:\temp\sorties ACM.htm" GPATH = "c:\temp" (URL=NONE) ; Et ODS HTML CLOSE ;
après l'instruction RUN ; à la fin du programme.
Non seulement vos sorties seront plus jolies dans une page Web (changer éventuellement c:\temp pour un autre répertoire dans les deux options qui y font référence) mais en plus ODS GRAPHICS ajoutera directement le premier plan factoriel dans l'espace des variables : il ne vous reste "qu'à" fusionner les modalités qui sont proches dans ce plan.Réseau de neurones
PRELIMINARY RUNS : éventualité de faire un premier ajustement des poids synaptiques (coefficients du réseau) parce qu'on ne trouve pas qu'il arrive correctement au minimum d'erreur possible. Généralement inutile à paramétrer.
TRAINING TECHNIQUE : algorithme cherchant un minimum de la fonction d'erreur. DEFAULT correspond à un algorithme très respecté, LEVENBERG-MARQUARDT. Il est néanmoins très coûteux en temps et en mémoire (il inverse une forme hermitienne de la matrice jacobienne, ça a peu d'importance pour la suite mais dans une conversation ça fait toujours bien !) sur les réseaux très complexes (3 neurones cachés ou plus, plusieurs couches cachées, beaucoup de variables en entrée, variable cible polytomique aux nombreuses valeurs). On lui préfèrera alors le gradient conjugué (CONJUGATE GRADIAN) qui est moins efficace, mais plus rapide. En résumé, ici encore, on peut garder le choix par défaut, sauf pour de gros réseaux.
Quel fonction de transfert utilise SEM pour les réseaux de neurone ? la logistique ?
Il utilise par défaut une tangente hyperbolique dans les perceptrons, une loi normale dans les RBF. Pour modifier cela, aller dans l'onglet ADVANCED, cliquer droit sur la couche cachée et choisir PROPERTIES, puis l'onglet HIDDEN. On a alors le choix pour ACTIVATION FUNCTION : logistique, tangente hyperbolique, gaussienne, arctangente, sinus, cosinus, etc...
Dans la sortie (output), à quoi correspond la table "weights" ? (on a des H11 - H12... cela correspond-il aux noeuds) et comment analyse-t-on le graph dans cet onglet (weight) ?
Il s'agit des poids synaptiques du réseau. On ne peut rien en tirer, si ce n'est l'équation du modèle dans les cas les plus simples (et encore... C'est tellement compliqué qu'on n'en retire aucune info). Le graphique est lui aussi largement inutile. Les sorties du RN de SEM ne se commentent pas vraiment (même pas du tout).
En faisant une modélisation sur SEM avec des réseaux de neurones, on obtient un taux de mal classés de 50% : alors, que doit-on faire ? Arrêter ?
Augmenter la taille de la couche cachée pourrait être une solution. Une deuxième couche cachée n'est utile que si vous avez des relations très très très complexes entre les entrées et les sorties. Sinon, on peut essayer en bougeant la limite du score : par défaut, il décide dans un sens ou dans l'autre autour de la valeur bascule de 0,5. Peut-être qu'on aurait moins de mal classés en décalant cette limite, ou en créant une zone d'incertitude (zone de non-décision).
J'ai besoin d'utiliser les réseaux de neurones sous SEM. Tout d'abord peut-t-on utiliser une variable "target" avec plusieurs modalités? Je n'ai pas de problèmes pour les lancer mais je ne sais pas trop comment les interpréter, à part le "misclassification rate"... Dans l' "output validation data", il n'y a pas de variables permettant de savoir où les individus ont été classés...
Pas de contre-indication à modéliser une variable continue avec les RN de SAS, l'inconvénient étant la difficulté d'évaluer la qualité du modèle. Et en plus, son opacité est grande (mais c'est toujours le cas avec les RN !). Il n'y a pas grand-chose à tirer des sorties proposées par SAS, et globalement pas grand-chose à y faire. Pour voir les valeurs proposées par SEM, il faut enchaîner un nœud Assessment où on ne fait rien de spécial sinon accepter ce modèle, et un noeud Score qui score la table de départ. Alors on pourra voir les prédictions, et même plus (graphique, procédures statistiques,...) : elles se trouvent dans une table &_SCORE, sous le nom de P_nomDeLaVariableAPrédire. Si tu as une autre variable continue, je propose par exemple ce programme :
symbol1 i=join l=1 ; symbol2 i=join l=2 ; proc gplot data = &_score ; plot (y p_y) * x / overlay ; run ; quit ;
Il n'y a qu'à remplacer les x et les y par les noms de variables Input et Target réciproquement. On peut faire ça dans un noeud SAS Code pour l'intégrer au diagramme (il faut l'enchaîner après le nœud Score) ou directement dans le program editor après exécution du noeud Score.
SAS/AF
FILENAME test EMAIL TYPE = "TEXT/HTML" SUBJECT = "Ceci est un test" ; DATA _NULL_ ; INFILE CARDS DLM = "/" MISSOVER ; FILE test ; INPUT nom :$30. ; nom = UPCASE(nom) ; PUT "!EM_TO! " nom ; DETALINES; contact@od-datamining.com olivier decourt ; RUN ;
proc build catalog = maBib.appliDef ; /* catalogue de l'appli livrée */ merge catalog = maBib.appliDvp /* catalogue de l'appli de développement */ NOSOURCE ; /* source non visible */ run ;
SAS/Base
DATA work.test ; INPUT variable1 & :$30. ; DATALINES ; Il fait beau Toto fait ses devoirs ; RUN ; DATA work.test ; SET work.test ; LENGTH debutsMots $ 10 ; numMot = 1 ; debutsMots = "" ; DO WHILE (SCAN(variable1,numMot) NE "") ; debutsMots=COMPRESS(debutsMots!!SUBSTR(SCAN(variable1,numMot),1,1)) ; numMot = numMot + 1 ; /* mot suivant */ END ; RUN ;
Nom_complet = TRIM(prenom)!!" "!!TRIM(nom) ;Ou, en SAS v9, utiliser la fonction STRIP (suppression des blancs à gauche et à droite), ou encore les fonctions CATT (concaténation et suppression des blancs à droite) ou CATX (concaténation, élimination des blancs à gauche et à droite, insertion d'un caractère séparateur) :
Nom_complet = CATX(" ", civilite, prenom, nom) ;
PROC SORT DATA = mesDonnees ; BY nom prenom adresse ; RUN ; DATA mesDonnees ; SET mesDonnees ; BY nom prenom adresse ; RETAIN identifiant 0 ; IF FIRST.adresse THEN identifiant = identifiant + 1 ; RUN ;
FILENAME test EMAIL TYPE = "TEXT/HTML" SUBJECT = "Ceci est un test" ; DATA _NULL_ ; INFILE CARDS DLM = "/" MISSOVER ; FILE test ; INPUT nom :$30. ; nom = UPCASE(nom) ; PUT "!EM_TO! " nom ; DETALINES; contact@od-datamining.com olivier decourt ; RUN ;
data ww.CMb; set ww.CM1b ww.CM2b ... ww.CM40b; run;Merci Bonjour, et merci de votre question. Vous pouvez utiliser un programme comme celui-ci :
%MACRO empilement (nbTables) ; DATA ww.CMb ; SET %DO i=1 %TO &nbTables ; ww.CM&i.b %END ; ; RUN ; %MEND empilement ;
%empilement (40)A partir de SAS 9.2, plus besoin de macros ! Vous pouvez écrire directement
SET ww.CM1-ww.CM40 ;dans votre étape Data. Par contre, comme dans votre cas le nom des tables ne se termine pas par un nombre, il faudra rester à la solution macro.
proc transpose data=infic prefix=cnt out=outfic; var nocnt; by client; run ;va générer cnt1 à cntn. Comment récupérer le nombre de variables générées (n) dans une étape data ? Merci. Pour mettre ce nombre dans une macro-variable, voici un premier programme :
DATA _NULL_ ; SET outfic ; ARRAY transpose cnt: ; CALL SYMPUT ("nbNllesVar", DIM(transpose)) ; STOP ; RUN ;Vous récupérez le nombre de variables créées par la procédure TRANSPOSE dans la macro-variable &nbNllesVar. Pour disposer de ce nombre sous forme de variable dans l'étape Data, il suffit de modifier légèrement ce programme :
DATA ... ; SET outfic ; ARRAY transpose cnt: ; nbVar = DIM(transpose) ; /* il est également possible d'opérer des traitements avec une boucle sur l'Array : DO i = 1 TO DIM(transpose) ; traitement sur transpose(i) END ; */ RUN ;
%macro essai; data table; input variable; cards; 1 2 3 ; run; %mend essai; %essai; ERROR: The macro ESSAI generated CARDS (data lines) for the DATA step, which could cause incorrect results. The DATA step and the macro will stop executing. NOTE: The data set WORK.TABLE has 0 observations and 1 variables.Bonjour. Effectivement, l'emploi de CARDS, CARDS4 et DATALINES est interdit dans un macro-programme. La raison est sans doute la difficulté prévisible de bien repérer les données proposées. Une alternative sera de mettre les données dans un fichier texte et de le lire avec INFILE ... INPUT.
- attention à ne pas confondre LENGTH et FORMAT ; le premier est le nombre d'octets sur lequel une valeur est stockée et le second une indication de la manière dont les valeurs sont affichées. Dans le cas d'une variable caractère, les deux sont souvent semblables : une variable stockée sur 3 octets s'affiche sur 3 caractères (LENGTH=$ 3 et FORMAT=$3.). Pour les variables numériques, on a un LENGTH de 8 (par défaut) et un affichage assez libre : BEST12. signifie juste que SAS utilisera au plus 12 caractères pour afficher la valeur. Le LENGTH de 8 est approprié si la variable contient des décimales. Sinon, selon son ordre de grandeur, on peut gagner de la place avec un LENGTH plus court, entre 3 et 7.
- la compression n'est pas un moyen de gagner du TEMPS mais de la PLACE. Je n'ai pas l'impression que ce soit votre but ; en effet, une table compressée (zippée en interne par SAS) nécessite plus de temps à s'ouvrir (il faut la décompresser) et à s'écrire (il faut la recompresser). Ce n'est donc pas forcément la solution espérée.
data format.fmtDRCourt; set tdbprod.BaseCourtiers (keep=gc DR rename=(gc=start dr=label)); by start; type="N"; /* N Numérique */ fmtname="DRCOURT"; run; proc format lib=format cntlin = format.fmtDRCourt /*fmtlib*/; run;
Je vous propose la variante suivante. DATA format.fmtDRCourt ; SET tdbprod.BaseCourtiers (KEEP = gc dr RENAME=(gc=start)) ; BY start ; LENGTH label $32 ; type="N" ; /* N Numérique */ fmtname="DRCOURT" ; IF _N_=1 THEN DO ; hlo = "O" ; /* ligne OTHER */ label = "Autres" ; OUTPUT ; END ; hlo = " " ; label = dr ; /* ou PUT(dr, format.) si DR est une variable numérique */ OUTPUT ; RUN ; PROC FORMAT LIB=format CNTLIN = format.fmtDRCourt FMTLIB ; RUN ;La variable HLO (High, Low, Other) permet de repérer les lignes "spéciales" dans le descriptif d'un format : celles qui utilisent un de ces trois mots-clés. La variable HLO vaut alors "L", "H" ou "O" selon les cas.
proc format; value anccrea low- mdy(12,31,2002) = "1- avant 01/2003" mdy(12,31,2002)-mdy(12,31,2004)= "2- entre 2003 et 2004 " mdy(12,31,2004)-high= "3- depuis 2005 " other ="???"; run;et ça
proc format; value anccrea low- '31/12/2002'd = "1- avant 01/2003" ...Merci. La 2e solution n'était pas bien loin du compte. Simplement, la forme de la date entre guillemets doit être JJ puis mois sur 3 lettres en anglais puis année. Comme dans un WHERE.
PROC FORMAT ; VALUE anccrea LOW- '31dec2002'd = "1- avant 01/2003" ... ; RUN ;
proc format; value $test '10' = 'l'arbre'; run;Comment faire comprendre à SAS qu'il ne s'agit pas de la fin du label ? Merci Bonjour. Le plus simple pour résoudre votre problème est tout simplement d'écrire votre libellé entre guillemets doubles. Il n'y aura alors pas de confusion avec les apostrophes. Dans SAS, les guillemets doubles et les apostrophes sont totalement équivalents, à condition qu'ils soient par paires identiques (= quand on ouvre des guillemets doubles, on ferme des guillemets doubles). La seule différence tient à un texte contenant une référence à une macro-variable &nomMV. Entre guillemets simples (apostrophes), la macro-variable ne sera pas résolue ; entre guillemets double, elle le sera.
proc format; value $test '10' = "l'arbre"; run;
- de filtrer les données en amont avec un WHERE
- d'utiliser un format pour associer les valeurs des valeurs des variables CLASS à ne pas afficher avec des valeurs manquantes (par défaut, la procédure Tabulate n'affiche pas les valeurs manquantes)
PROC TABULATE DATA = ... FORMAT = NUMX12.2 ;devrait faire l'affaire.
OPTION LOCALE = FRENCH ;par exemple en début de programme SAS, en dehors de toute procédure et étape Data.
proc format; value pop (multilabel) low-35="35 ans et moins" low-high/* ?? */="tout le monde"; run;mais si j'applique ce format dans une proc freq par exemple:
proc freq data=****; table age; format age pop.; run;j'obtiens bien les 35 ans et moins d'une part, mais dans "tout le monde" je n'ai que les plus de 35 ans. Comment obtenir l'ensemble de la population? Merci pour votre réponse Bonjour. Il n'est malheureusement pas possible d'utiliser les formats MULTILABEL partout. Seules les procédures MEANS et TABULATE les supportent. Une alternative pour votre problème : dupliquer les observations correspondant aux moins de 35 ans, avec une étape Data.
DATA work.pour_etude ; SET *** ; IF age < 35 THEN DO ; doublon = 1 ; OUTPUT ; END ; doublon = 0 ; /* pour tout le monde */ OUTPUT ; RUN ;Ensuite il suffit d'habiller la variable DOUBLON avec un format : 0 -> tout le monde 1 -> moins de 35 ans.
PROC FORMAT ; PICTURE milliers (ROUND) 0 - HIGH = "000 000 009" ; RUN ;Vous utilisez ensuite le format milliers. quand vous en avez besoin. Pour plus d'informations sur les formats "picture", voir Les pictures expliqués à ma fille.
- pour que les titres des instructions TITLE apparaissent en tête de chaque onglet; ajoutez l'option EMBEDDED_TITLES="YES" aux spécifications d'ODS TAGSETS.EXCELXP
- si vous souhaitez conserver un titre visible à l'impression, vous pouvez l'indiquer avec l'option PRINT_HEADER="ici titre personnalisé", toujours dans l'instruction ODS TAGSETS.EXCELXP.
ODS TAGSETS.EXCELXP FILE="c:\temp\titres.xls" OPTIONS(EMBEDDED_TITLES="YES" PRINT_HEADER="%NRSTR(&E)Tout le classeur porte sur la table SASHELP.CLASS" SHEET_NAME="Détail" SHEET_INTERVAL="PROC") ; TITLE1 "Liste des enfants" ; PROC PRINT DATA=sashelp.class NOOBS ; RUN ; ODS TAGSETS.EXCELXP OPTIONS(SHEET_NAME="Stats") ; TITLE1 "Statistiques" ; PROC FREQ DATA=sashelp.class ; TABLE sex age ; RUN ; TITLE ; ODS TAGSETS.EXCELXP CLOSE ;
ODS RTF FILE="c:\temp\test vertical.doc" ; PROC REPORT DATA=sashelp.shoes SPLIT=" " NOWD ; COLUMNS _ALL_ ; RUN ; ODS RTF CLOSE ;Ici l'espace sert d'indication pour revenir à la ligne, mais on peut modifier les labels pour incruster à l'endroit voulu (y compris après chaque lettre !) un caractère de retour à la ligne.
PROC CONTENTS DATA=sashelp.shoes OUT=work.labels (KEEP=name label) NOPRINT ; RUN ; DATA _NULL_ ; SET work.labels END=fin ; LENGTH newLabel $ 200 ; newLabel = PRXCHANGE("s/(.)/¤$1/",-1,STRIP(COALESCEC(label,name))) ; newLabel = SUBSTR(newLabel,2) ; /* élimine le 1er ¤ ajouté en tête */ IF _N_=1 THEN CALL EXECUTE ("DATA work.export ; SET sashelp.shoes ; LABEL ") ; CALL EXECUTE (name !! "=" !! QUOTE(STRIP(newLabel))) ; IF fin THEN CALL EXECUTE ("; RUN ;") ; RUN ; ODS RTF FILE="c:\temp\test vertical.doc" ; PROC REPORT DATA=work.export SPLIT="¤" NOWD ; COLUMNS _ALL_ ; RUN ; ODS RTF CLOSE ;
proc template; define style styles.noborder; parent=styles.minimal; style Pays / just = center; end; run; ODS HTML FILE='Edition.xls' STYLE=styles.noborder; title; Proc print data=final noobs; Run; ods HTML close ;Merci d'avance. Je vous conseillerais d'aller agir directement dans la procédure Print, qui le permet, plutôt que dans la procédure Template, qui accepte mal les cas particuliers de mise en forme par colonne.
ODS HTML FILE='Edition.xls' STYLE=minimal ; TITLE ; PROC PRINT DATA=final NOOBS ; VAR entite ; VAR pays / STYLE = [JUST=CENTER] ; VAR ; RUN ; ODS HTML CLOSE ;Attention cependant, selon les versions, Excel n'applique pas toujours les consignes de centrage. Si vous possédez SAS 9 et Excel 2003, je vous conseille plutôt de passer par la destination ODS TAGSETS.EXCELXP que par ODS HTML.
ODS ODS TAGSETS.EXCELXP FILE='Edition.xls' STYLE=minimal ; title; Proc print data=final noobs; VAR entite ; VAR pays / STYLE = [JUST=CENTER] ; VAR ; Run; ods ODS TAGSETS.EXCELXP close ;
- pour toutes versions de SAS depuis la 8.0, vous pouvez ouvrir une destination ODS HTML sur le même principe qu'ODS RTF, en indiquant dans FILE= un fichier dont l'extension est .XLS. Vous ne créerez pas une feuille Excel au sens strict, mais une page Web qu'Excel sait lire à partir de la version 1997
- pour SAS 9.1 et Excel 2003 minimum, vous pouvez utiliser ODS TAGSETS.EXCELXP qui va créer un (presque) véritable classeur Excel. La documentation sur cette destination et ses options peut s'afficher dans la fenêtre Log en exécutant le programme suivant :
ODS TAGSETS.EXCELXP OPTIONS(DOC="help") FILE = "c:\temp\rien.xls" ;
- pour SAS 9.4 et Excel 2007 minimum, vous pouvez utiliser ODS EXCEL qui va créer un véritable classeur Excel d'extension XLSX.
filename sortie DDE "excel|Feuil1!l1c2:l1c79" notab; DATA _null_; SET pgm; FILE sortie; PUT COL1 '09'x COL2 '09'x COL3 '09'x COL4 '09'x COL5 '09'x COL6 '09'x COL7 '09'x COL8 '09'x COL9 '09'x COL10 '09'x COL11 '09'x COL12 '09'x COL13 '09'x COL14 '09'x COL15 '09'x COL16 '09'x COL17 '09'x COL18 '09'x COL19 '09'x COL20 '09'x COL21 '09'x COL22 '09'x COL23 '09'x COL24 '09'x COL25 '09'x COL26 '09'x COL27 '09'x COL28 '09'x COL29 '09'x COL30 '09'x COL31 '09'x COL32 '09'x COL33 '09'x COL34 '09'x COL35 '09'x COL36 '09'x COL37 '09'x COL38 '09'x COL39 '09'x COL40 '09'x COL41 '09'x COL42 '09'x COL43 '09'x COL44 '09'x COL45 '09'x COL46 '09'x COL47 '09'x COL48 '09'x COL49 '09'x COL50 '09'x COL51 '09'x COL52 '09'x COL53 '09'x COL54 '09'x COL55 '09'x COL56 '09'x COL57 '09'x COL58 '09'x COL59 '09'x COL60 '09'x COL61 '09'x COL62 '09'x COL63 '09'x COL64 '09'x COL65 '09'x COL66 '09'x COL67 '09'x COL68 '09'x COL69 '09'x COL70 '09'x COL71 '09'x COL72 '09'x COL73 '09'x COL74 '09'x COL75 '09'x COL76 '09'x COL77 '09'x COL78 '09'x; RUN;Or, sur ma feuille Excel, seules les 22 premières variables sont inscrites. Si je diminue le format de mes variables au minimum (format 3.2), j’arrive à obtenir les 64 premières variables. Mais j’ai toujours une perte d’informations… Comment puis-je faire ? Le problème vient de la largeur du "tuyau" utilisé par SAS pour envoyer les infos à Excel ; par défaut, il ne fait que 256 octets, ce qui ne permet pas de véhiculer les valeurs de vos 78 variables. On peut augmenter cette largeur de tuyau avec l'option LRECL (Logical RECord Length) dans l'instruction FILE.
... FILE sortie LRECL = 4000 ; ...Le reste de votre programme, lui, n'a pas à changer.
ODS HTML FILE = "chemin et nom de votre fichier.xls" ; TITLE ; FOOTNOTE ; PROC PRINT DATA = votre_table LABEL NOOBS ; RUN ; ODS HTML CLOSE ;Vous obtiendrez ainsi une pseudo feuille Excel (en fait, c'est une page Web habillée d'une extension XLS, mais Excel 97 n'y verra que du feu). En revanche, pour pouvoir ajouter d'autres feuilles au classeur par la suite, il est recommandé d'ouvrir Excel, d'ouvrir la feuille créée et de la sauvegarder en forçant son type à "Classeur Excel". Plus proprement, mais uniquement si vous possédez le module ACCESS TO PC FILES, vous pouvez exporter directement dans une vraie feuille Excel ainsi :
PROC EXPORT DATA = votre_table OUTFILE = "chemin et nom de votre fichier.xls" REPLACE DBMS = EXCEL97 ; RUN ;Pour savoir si vous possédez ledit module, exécutez le programme suivant :
PROC SETINIT NOALIAS ; RUN ;et regardez dans la Log. Si une ligne "SAS/ACCESS Interface to PC Files" y apparaît (ou un intitulé approchant, il varie selon les versions), c'est bon. Sinon, il faudra opter pour la première solution.
- remplacer tous les points du tableau par des virgules sous Excel (avec un Remplacer)
- changer le séparateur décimal (Menu Démarrer de Windows, Panneau de Configuration, Paramètres Régionaux, onglet Nombres) de la virgule pour le point.
- si le tableau est généré par une PROC TABULATE, rajouter à l'instruction TABLE qu'il faut employer des formats NUMXx.y, qui fonctionnent comme les formats numériques x.y habituels, mais affichent une virgule comme séparateur décimal ! Pour cela, la commande à insérer est *format=NUMX12.2 par exemple.
- si le tableau est généré par une PROC PRINT, une PROC TABULATE ou une PROC REPORT, utiliser les instructions de formatage avec l'attribut de style TAGATTR qui permet d'envoyer à Excel des indications de format de cellule (cf. L'export de SAS vers Excel expliqué à ma fille)
Bonjour, J'essaye d'utiliser la fonction week dans mon programme, pour convertir une date en découpage hebdo. Il semble que cette fonction ne soit pas reconnue. Je suis actuellement en SAS V8, est-ce que cette fonction n'est dispo qu'en V9 ? Je vous remercie pour vos réponses. Bonne journée !
Bonjour. Effectivement la fonction WEEK est nouvelle avec la version 9. A l'utilisation, elle nécessite un 2e argument, "V" ou "W" pour indiquer le mode de calcul des numéros de semaine. Les semaines commencent le lundi et la semaine n°1 commence au 1er lundi de janvier. Les jours précédant le 1er lundi de janvier appartiennent à la semaine 52 si on indique "V", ou la semaine 0 avec "W".
En version 8, vous devez utiliser la fonction INTCK qui calcule le nombre de lundis entre 2 dates (WEEK.2 désigne des semaines commençant le lundi) : semaine=INTCK("WEEK.2", MDY(1,1,YEAR(maDate)), maDate) ; Avec cette formule, les jours précédant le 1er lundi de janvier appartiendront à la semaine 0.Bonjour, je dispose d'une table avec des dates sous un certain format. je voudrais savoir comment les afficher via une proc freq sans format, c'est-à-dire en les visualisant sous la forme du nombre de jour depuis le 1er JAN 1960. L'objectif étant de récupérer les dates distinctes de ma table dans une liste, et de boucler dessus. Par avance, merci.
Bonjour.
Pour répondre directement à votre question, ajoutez une instruction FORMAT maVariableDate 6. ; à votre procédure FREQ. Sinon, vous pouvez directement créer une table de dates distinctes avec une procédure SORT avec l'option NODUPKEY, sans avoir besoin de la proc FREQ.
Bonjour. J'ai une date de format $10. (style 10/10/2010) que je voudrais transformer en date DDMMYY10. Merci d'avance de votre réponse.
Bonjour.
Il faudra créer une nouvelle variable, de type numérique ; pour cela, en SQL ou dans une étape Data, la formule sera INPUT(variableExistante, DDMMYY10.) et le résultat sera en nombre de jours depuis le 01/01/1960. Restera ensuite à l'habiller du format date de votre choix.
Bonjour,
j'ai une variable date dans un fichier, et je souhaite faire la répartition en fonction de tranche gérées par un format que je crée... et je n'arrive pas à créer ce format (sans passer par le calcul du nombre de jours correspondants à ma date..)
j'ai essayé ça :
proc format; value anccrea low- mdy(12,31,2002) = "1- avant 01/2003" mdy(12,31,2002)-mdy(12,31,2004)= "2- entre 2003 et 2004 " mdy(12,31,2004)-high= "3- depuis 2005 " other ="???"; run;et ça
proc format; value anccrea low- '31/12/2002'd = "1- avant 01/2003" ...
Merci.
La 2e solution n'était pas bien loin du compte. Simplement, la forme de la date entre guillemets doit être JJ puis mois sur 3 lettres en anglais puis année. Comme dans un WHERE.
PROC FORMAT ; VALUE anccrea LOW- '31dec2002'd = "1- avant 01/2003" ... ; RUN ;
Bonjour.
J'aurais souhaité afficher une date sous la forme suivante : Janvier 2005 (en français, mais sans le numéro du jour).
D'avance merci.
Bonjour.
Si vos données sont sous forme de dates SAS, vous pouvez utiliser :
- les formats "français" de dates de SAS, comme FRADFWDX. qui afficherait 01 janvier 2005 ;
- un format de type particulier, appelé PICTURE, créé par la procédure FORMAT. Dans le cas de votre demande, c'est ce qu'il convient d'utiliser :
PROC FORMAT ; PICTURE testDate LOW - HIGH = '%B %Y' (DATATYPE = DATE) ; RUN ;
Dans cette syntaxe, l'option DATATYPE = DATE permet de spécifier le type de données lues. On peut également avoir deux autres valeurs, TIME et DATETIME.
Les éléments %Y, %B qui composent la valeur affichée sont des mots-clés reconnus de la procédure FORMAT. Les principaux éléments sont :
- %a = jour de la semaine en français sur 3 lettres
- %A = jour de la semaine en français
- %b = mois sur 3 lettres en français
- %B = mois en français
- %d = jour du mois sans zéro initial
- %0d = jour du mois sur deux chiffres
- %j = jour de l'année (de 1 à 366)
- %m = mois (1 à 12) sans zéro initial
- %0m = mois sur deux chiffres
- %0y = année sur deux chiffres
- %Y = année sur quatre chiffres
Enfin, il est recommandé d'employer des apostrophes et non des guillemets autour de la valeur formatée afin d'éviter toute intervention du compilateur macro.
Comment positionner des lignes concernant le même identifiant les unes à la suite des autres ? Par ex:
identifiant | nom | prenom | date naissance |
111 | durand | paul | 01/10/1987 |
111 | durand | guy | 26/01/1999 |
111 | durand | pierre | 13/09/2001 |
333 | dupont | jack | 16/12/2004 |
Le problème est de positionner la famille durand , identifiant 111, sur la même ligne. Je vous remercie.
Bonjour, et merci de votre question.
Ce genre de "pivotage" de données n'est pas simple, et SAS ne fait pas grand-chose pour nous y aider. Il faut utiliser la procédure TRANSPOSE, sur chacune des variables à pivoter (ici, PRENOM et DATE DE NAISSANCE. On obtient plusieurs tables que l'on combinera dans une étape Data, avec plusieurs instructions SET. Le programme suivant résume les manipulations à effectuer...
DATA work.test ; INPUT id nom $ prenom $ dtnais DDMMYY10. groupe_sanguin $ ; CARDS ; 111 durand paul 01/10/1987 AB 111 durand guy 26/01/1999 A 111 durand pierre 13/09/2001 A 111 durand karl 14/10/2002 O 111 durand marie 14/10/2002 A 111 durand ulysse 25/01/2004 B 111 durand éléonore 25/01/2004 A 111 durand garance 25/01/2004 B 111 durand télémaque 25/01/2004 AB 111 durand vanessa 07/09/2005 A 111 durand armelle 07/09/2005 O 333 dupont jack 16/12/2004 AB ; RUN ; PROC SORT DATA = work.test ; BY id nom ; RUN ; PROC TRANSPOSE DATA = work.test OUT = work.res1 (DROP = _NAME_) PREFIX = prenom ; BY id nom ; VAR prenom ; RUN ; PROC TRANSPOSE DATA = work.test OUT = work.res2 (DROP = _NAME_) PREFIX = dtnais ; BY id nom ; VAR dtnais ; FORMAT dtnais DDMMYY10. ; RUN ; PROC TRANSPOSE DATA = work.test OUT = work.res3 (DROP = _NAME_) PREFIX = gpe_sanguin ; BY id nom ; VAR groupe_sanguin ; RUN ; DATA work.fus ; SET work.res1 ; SET work.res2 ; SET work.res3 ; BY id nom ; RUN ;
Je tiens à remercier Bernard Gestin de m'avoir soufflé cette solution plus simple que celle que j'avais proposée initialement.
Bonjour.
Dans une table SAS que j'ai récupérée, j'ai une variable qui contient manifestement une date, qui semble numérique sur une longueur de 8, mais elle a un aspect bizarre. Une valeur, par exemple, est : 14JUN1977:00:00:00. Les fonctions dates habituelles (YEAR, INTNX, etc.) me renvoient des résultats aberrants quand je les applique à cette variable. Que faire ?
D'avance merci.
Vous êtes en présence d'une variable de "type" Datetime (stockée en nombre de secondes depuis le 01/01/1960 à minuit). C'est donc bien du numérique sur 8 octets (8 octets ça permet de stocker des entiers énormes). Mais ce n'est pas une DATE au sens où les fonctions comme YEAR s'y attendent, c'est à dire un nombre de jours depuis le 01/01/1960. Quant à son aspect "bizarre", il s'explique par un format DATETIME. spécialement conçu pour ce type d'information.
La fonction DATEPART permet d'extraire la partie "date" d'un Datetime. Mais il faut bien penser à affecter un format date (DDMMYY10. par exemple) à la variable ainsi créée.
Une étape Data comme celle-ci résoud le problème :
DATA ma_nouvelle_table ; SET mon_ancienne_table ; variable_date = DATEPART(variable_datetime) ; FORMAT variable_date DDMMYY10. ; RUN ;
(Il convient bien sûr de changer les noms des tables et des variables pour coller à votre sujet.)
Bonjour, J’ai enregistré l'ensemble des commandes de mon batch dans un fichier txt. Quelles sont ensuite les commandes de lancement? D'avance merci
Bonjour.
Pour lancer un programme SAS en batch, la commande Unix correspond au raccourci qui lance habituellement SAS.
Il faut indiquer le programme à exécuter après l'option -SYSIN, entre guillemets.
Par exemple : "home/pgm/SAS9/sas.exe" -CONFIG "home/pgm/SAS9/SASV9.CFG" -SYSIN "home/users/perso/pgm.txt"
On peut récupérer la Log en indiquant un nom de fichier après l'option -LOG, et on doit indiquer des instructions ODS dans le programme à exécuter pour récupérer aisément les sorties. Si vous utilisez habituellement un autoexec, il est préférable d'indiquer celui-ci au début du programme à exécuter : par exemple :
%INCLUDE "home/users/perso/autoexec.sas" ; /* début du programme soumis en batch... */ DATA work.test ; SET etc.
Bonjour,
je travaille sur serveur et souhaiterais enregistrer mes tables sur le serveur sous un autre format que le format SAS (pour importation sous BO designer par la suite). Merci d'avance.
Bonjour.
Pour l'export vers Business Objects, le type de fichier le plus simple à transmettre depuis SAS est un fichier texte à séparateur tabulation. On peut le produire, avec une version 8 ou supérieure, à l'aide de la procédure EXPORT, comme le titre de votre question le suggérait :
PROC EXPORT DATA = sashelp.class OUTFILE = "~/test.dat" DBMS = TAB ; RUN ;
Le répertoire ~ est la racine de votre compte utilisateur.
L'autre option est d'utiliser un peu de macro-langage et au final une étape Data pour réaliser cet export. Le macro-langage récupère auprès du dictionnaire des données (créé par la PROC CONTENTS) une liste de noms de variable pour l'en-tête du fichier, et une liste de noms de variables pour l'export proprement dit. Ces créations de macro-variables se font dans une procédure SQL. Enfin, une étape Data d'export "classique" avec instructions SET, FILE et PUT, permet d'écrire dans le fichier voulu.
PROC CONTENTS DATA = sashelp.class OUT = work.dico NOPRINT ; RUN ; PROC SQL NOPRINT ; SELECT QUOTE(LEFT(TRIM(name))), LEFT(TRIM(name)) INTO : liste_en_tete SEPARATED BY " '09'x ", liste_variables SEPARATED BY " '09'x " FROM work.dico ORDER BY varnum ; QUIT ; DATA _NULL_ ; SET sashelp.class ; FILE "c:\test.dat" ; IF _N_ = 1 THEN PUT &liste_en_tete ; PUT &liste_variables ; RUN ;
Le charme de ces deux programmes est qu'ils ne nécessitent jamais l'énumération des noms des variables (pratique quand on possède des dizaines ou des centaines de colonnes dans la table à exporter).
Je souhaite allouer une librairie qui pointerait sur des données situées sur un serveur UNIX qui n'est pas celui sur lequel est installé le SAS que j'utilise.Cependant, si cela est utile, le logiciel SAS est installé sur les 2 serveurs.
Y-a-t-il une (ou plusieurs ??) solutions ?
Merci d'avance,
La présence de SAS sur le second serveur évite la solution assez brutale de devoir transférer (via FTP par exemple, ou un FILENAME FTP au mieux) les données d'un serveur à l'autre.
Deux solutions se profilent à ce problème :
- Faire travailler directement le second serveur, celui où se trouvent les données. Un RSUBMIT ... ENDRSUBMIT permet de lui faire effectuer le maximum de traitement. Pour rappatrier ensuite les données obtenues (si le but est de les exploiter sur le "premier" serveur), une procédure DOWNLOAD fera l'affaire. (Les syntaxes sont précisées en fin de réponse.
- La deuxième (et certainement pas dernière) solution consiste à déclarer sur le "premier" serveur une bibliothèque RLS, c'est à dire une image, un pointeur, un lien vers une bibliothèque du second serveur. On considère alors les données de cette bibliothèque comme toutes celles qui se trouvent sur le premier serveur. Les temps de réponse de cette solution seront certainement médiocres. Mais sa simplicité est maximale.
Syntaxe pour le RSUBMIT : RSUBMIT ; PROC xxx ... ; ... RUN ; ENDRSUBMIT ;
Syntaxe pour la proc DOWNLOAD : RSUBMIT ; PROC DOWNLOAD DATA = tableSASserveur2 OUT = tableSASserveur1 ; RUN ; ENDRSUBMIT ;
Syntaxe pour le RLS : RSUBMIT ; LIBNAME toto "chemin" ; ENDRSUBMIT ; LIBNAME Rtoto SLIBREF = toto SERVER = nomDuServeur ;
La démarche suivante pose problème :
- j'ai créé un échantillon sur ma session Unix...
- je l'ai transféré en tant que fichier à plat sur Windows NT
- je l'ai importé sous SEM...
le problème qui se pose : des variables qui étaient dans ma base de départ de type char deviennent de type num... j'ai voulu les modifier dans un noeud IDS mais ça ne fonctionne pas... Y a t-il un autre moyen?
Il s'agit en fait d'un problème d'importation de SAS lui-même, pas spécifique à SEM. Il prend comme numériques toutes les variables n'ayant que des valeurs chiffrées (même s'il s'agit de codes). Le plus simple est peut-être de faire l'import à la main avec une étape Data et une instruction INPUT.
Je travaille en client/serveur. Je crée en RSUBMIT des formats avec une PROC FORMAT. Je fais une option FMTSEARCH sur la librairie qui contient le catalogue de formats. Pour l'exécution de procédures, tout va bien. Mais quand je veux regarder ma table avec l'Explorer, SAS me dit qu'il ne trouve pas les formats. Que se passe-t-il ?
LE PROBLEME : l'architecture client/serveur ne fait pas transiter les formats. Cela implique entre autres qu'on ne peut pas utiliser sur le client les formats du serveur et vice-versa, et que l'on ne peut pas créer sur le serveur des formats depuis le poste client (même dans un RSUBMIT).
LA SOLUTION : Première étape, créer le(s) format(s) en LOCAL. Donc sur le PC. Pour cela, exécuter EN-DEHORS du bloc RSUBMIT / ENDRSUBMIT la procédure formats avec une syntaxe
PROC FORMAT LIB = librairie_locale ; etc... RUN ;
Deuxième étape, le catalogue FORMATS créé dans la librairie locale doit être "remonté" sur le serveur. Pour cela, SUR LE SERVEUR cette fois (dans un bloc RSUBMIT / ENDRSUBMIT), utiliser la PROC UPLOAD qui est dédiée à la copie de "membres" SAS d'une librairie client dans une librairie distante du serveur. Si, par exemple, vous avez stocké les formats dans WORK.FORMATS, vous les remonterez ainsi vers ServLib.FORMATS :
PROC UPLOAD INCAT = WORK.FORMATS OUTCAT = ServLib.FORMATS ; RUN ;
Bonjour, je suis en stage et je voudrais réaliser un arbre de décision sous SAS. Je voudrais connaître la forme du programme permettant de construire un arbre de décision sous SAS. Merci d'avance
Il n'existe malheureusement pas de programme existant directement dans SAS pour réaliser des arbres de décision. Ceux-ci peuvent être produits avec l'interface SAS Enterprise Miner, qui fait l'objet d'un module facturé en sus.
A partir de SAS 9.4, on peut cependant produire des arbres de décision avec la procédure HPSPLIT de SAS/STAT.
SAS/Stat
- soit vous avez peu de contrats auto récents (mettons quelques centaines seulement) et il faudra probablement ouvrir un petit peu la plage temporelle pour construire une base d'étude avec, au moins, un millier de contrats auto, et un millier de clients n'en ayant pas ;
- soit vous avez déjà, avec les nouveaux clients auto des deux années écoulées, des volumes suffisants, et le risque d'aller chercher les clients plus anciens serait de prendre un compte un profil qui n'est plus ceux des clients qui vous rejoignent actuellement. (Pour des raisons d'évolution de tarifs, de concurrence, d'image, de campagne publicitaire, ceux qui ont souscrit il y a, mettons, 5 ans, ne le feraient peut-être plus chez vous aujourd'hui, et ne restent que par inertie.)
- choisir un seuil pour transformer les prédictions continues (le score) en prédictions binaires (par exemple : 0,5 : si P_1 < 0,5 alors Ypredit = 0, sinon Ypredit=1)
- calculer la nouvelle variable binaire Ypredit
- la croiser (dans une proc Freq) avec la variable Yobservé
- additionner les pourcentages (2e ligne de chaque case) des cellules dans la diagonale du tableau (correspondances entre Yobservé et Y prédit).
CLASS variablesQuali / PARAM = GLM ;donne des coefficients de référence égaux à zéro. C'est le choix par défaut dans GENMOD.
CLASS variablesQuali / PARAM = REF ;donne des contraintes pour que l'ensemble des coefficients d'une variable qualitative soit nul. C'est le choix par défaut dans LOGISTIC.
PROC GLM DATA = tableSAS ; CLASS listeVariablesQuali ; MODEL variableY = listeVariablesQuantiEtQuali / ESTIMATE ; LSMEANS variableQuali / PDIFF=ALL ; RUN ; QUIT ;Une remarque : si le nombre d'observations sur lesquelles vous modélisez est faible, trop de modalités à vos variables qualitatives risquent de faire baisser la robustesse de votre modèle, et alors sans doute faudra-t-il fusionner des modalités... Dans ce cas, les comparaisons 2 à 2 de modalités peuvent vous aider (instruction LSMEANS ci-dessus). Une seconde remarque : si la distribution de vos prix à modéliser suit une loi normale, les procédures REG et GLM sont effectivement appropriées. S'ils suivent plutôt une loi Gamma, il faudra passer à la procédure GENMOD.
- Dans la partie Fit Statistics, on retrouve les critères d'Akaike, de Schwartz et la log-vraisemblance
- Dans la partie Global Tests, on a les tests du chi2 associés au score, à la log-vraisemblance et à la statistique de Wald
MODEL Y = covariables / CTABLE PPROB = (listeDeSeuils) ;
OUTPUT OUT = table PRED = variableP ;on a dans variableP les valeurs prédites pour les données inconnues (ce qu'on appelle un score). Ces valeurs s'échelonnent de 0 à 1, on les lit comme des probabilités d'occurrence d'un évènement. A partir de SAS 9.3, on peut aussi utiliser l'instruction SCORE.
- Type I SS
- Type II SS
- Type III SS
- Types I et III : sommes de carrés sur les EFFETS SIMPLES. C'est à dire la contribution de chacune des variables explicatives, sans les croiser entre elles. Le type I les introduit dans le même ordre que dans l'instruction MODEL, tandis que le type III corrige le biais dû à cet ordre (en fait, c'est comme s'il n'en tenait pas compte).
- Types II : il inclut les effets croisés.
- Type IV : il permet de prendre en compte les données "trouées" (certains cas de figures ne se présentent pas).
ODS TRACE ON / LISTING ; PROC xxx ... ; ... RUN ; ODS TRACE OFF ;Les informations sur chaque objet s'ajoutent dans la fenêtre Output. Une fois qu'on connaît le nom (QUANTILES pour celui qui vous concerne), on peut écire :
PROC UNIVARIATE ... ; ... ODS OUTPUT quantiles = work.maTableSAS ; RUN ;ou, pour n'afficher que le tableau de quantiles :
ODS SELECT quantiles ; PROC UNIVARIATE ... ; ... RUN ; ODS SELECT ALL ;
ODS OUTPUT OddsRatios = nomTableSAS ;Pour fonctionner, il faut que cette instruction soit entre les instructions PROC LOGISTIC et RUN.
ODS EXCLUDE ALL ; /* plus aucune sortie sauf ODS OUTPUT */ PROC TTEST ... ; ... ODS OUTPUT ... ; RUN ; ODS SELECT ALL ; /* retour à la normale */
ODS OUTPUT ANOVA = work.maTable ; PROC REG DATA = ... ; ... RUN ; QUIT ;
ODS OUTPUT parameterEstimates = work.coeffs ;et vous retrouverez dans la table COEFFS de la bibliothèque WORK vos coefficients.
Bonjour,
je dispose d'une table SAS de la densité d'une variable discréte (modalité + proba) et je voudrais les quantiles mais la proc univariate n'accepte pas des valeurs < 1 dans son option FREQ. Comme j'ai certaines proba trés faibles si je multiplie ma freq par 1000, je risque de perdre de l'info et si je multiplie par un nombre trés grand, la proc TABULATE est limitée ! Y a-t-il une solution pour obtenir les centiles par exemple ?
Merci
Les procédures usuelles de calculs pour les quantiles ne supportent pas vraiment proprement les pondérations décimales (ni Univariate, ni Rank). La solution de contournement vient de la proc KDE, dont ce n'est pas le but premier, mais qui fournit ces calculs en annexe. Il suffit de lui indiquer les ordres des quantiles espérés dans l'instruction UNIVAR pour les lister, et on les récupère avec ODS OUTPUT.
ODS OUTPUT percentiles=work.quantiles ; PROC KDE DATA=sashelp.class ; UNIVAR weight / PERCENTILES=0 TO 100 BY 1 ; RUN ;
Bonjour et merci d'avoir répondu à mes précédentes questions.
Ma régression logistique concerne 39 651 individus. J'ai donc, dans un premier temps, effectué un échantillon équilibré à 50/50 et j'obtiens 2 204 individus (car 1 201 ont la modalité cible égale à 1). Par la suite il est nécessaire de réaliser un partitionnement 70/30. On m'a conseillé de prendre 70% pour l'entrainement et 30% pour la validation. Ce que je voudrais savoir c'est comment faire ce partitionnement sous SAS (et non Miner) ? Faut-il que les deux partitions soient elles aussi équilibrées en fonction de la cible (35% -- >0 et 35% -->1 pour l'entrainement et 15% -->0 et 15% -->1 ) ? Et à quel moment la partition à 30% va t-elle intervenir pour la validation ?
D'autre part, pour le seuil optimal, j'obtiendrai forcément 0,5 puisque mon échantillon est équilibré ? Cela n'est pas gênant ?
Le fait de travailler sur 70% des 2 204 individus ne fausse pas le modèle ?
Je vous remercie pour votre réponse.
Bonjour.
Partition 70/30 :
DATA work.train work.valid ; SET maBase ; alea = RANUNI(0) ; IF alea < .7 THEN OUTPUT work.train ; ELSE OUTPUT work.valid ; RUN ;
Seuil optimal :
Il sera sans doute aux alentours de 0,5, pas forcément exactement à cette valeur. En fait, le seuil optimal s'harmonise avec la valeur de la constante du modèle, ce ne sera donc pas faux de travailler ensuite sur une population non équilibrée avec ce seuil.
Volume de données :
70% de 2200 individus, ça en fait encore largement assez, sauf si vous avez 400 variables explicatives dans votre modèle.
Utilisation des données de validation :
On ne construit pas de modèle dessus, on se contente de leur appliquer le moteur de score (c'est à dire qu'on prédit avec le modèle). Et on comparer le taux de bien classés avec celui donné par les données d'entraînement. Ce taux est plus fiable (l'autre est biaisé vers 0), et la constance du taux est signe de robustesse.
Bonjour,
Je souhaiterai savoir comment faire un échantillonnage stratifié (sur une ou plusieurs variables qualitatives) avec la PROC SURVEYLECT comme le fait le noeud SAMPLING de SEM.
Pour cela, il faut trier au préalable la table selon la variable cible de l'étude. Puis déterminer la taille d'un demi-échantillon (ici, 1500 par exemple).
PROC SURVEYSELECT DATA = maTableSAStriée OUT = monEchantillonEquilibré SAMPSIZE = 1500 ; STRATA maVariableCible ; RUN ;
Suite à une modélisation de variable binaire, j'utilise la PROC LOGISTIC de SAS 8.2. - Pour espérer obtenir de meilleurs résultats, faut-il équilibrer ma population de clients et de non clients? Exemple: expliquer une situation Y=1 alors que 80% de la population étudiée a Y=1, donne-t-il un poids trop important à ce groupe de clients ? - L'équilibre doit-il se faire dans l'échantillon d'apprentissage (70% de la population totale) sans s'en occuper dans l'échantillon test? - Après avoir obtenu les coefficients estimés du modèle sur les variables explicatives significatives dans le journal via la procédure ou sous EM, comment puis-je appliquer ce modèle sur une autre population (présentant évidemment les mêmes variables explicatives) afin de tous les attribuer un score? Suis-je obligée de faire cette étape manuellement ? Merci beaucoup de votre aide.
Il est toujours préférable de travailler sur un échantillon équilibré. Pour pouvoir comparer les performances de votre modèle sur le corpus d'apprentissage et sur celui de test, il est préférable que les deux soient équilibrés.
L'utilisation des coefficients du modèle peut se faire via la procédure SCORE si les variables explicatives de votre modèle sont quantitatives, ou des indicatrices. La prise en compte par la proc SCORE des variables quali est très mauvaise. Sinon, il est possible d'effectuer automatiquement ces manipulations en écrivant un petit macro-programme.
A noter qu'à partir de la version 9, la proc LOGISTIC intègre une instruction pour préciser une table SAS à scorer.
Bonjour, si le CCC de la proc FASTCLUS est très très négatif, comment puis-je le corriger? J'ai essayé de changer le nombre de classes mais cela ne marche pas.
Bonjour. Les valeurs du CCC supérieures à 3, comme le raconte la doc SAS, sont une rareté sur de vrais jeux de données. En réalité, il arrive souvent qu'on ait des valeurs négatives de l'ordre de plusieurs centaines. L'important est déjà d'observer un pic du CCC pour un nombre de classes (il faut essayer des procédures FASTCLUS avec plusieurs nombres de classes et représenter une courbe avec le nombre de classes en abscisses et le CCC en ordonnées). Vous pouvez aussi essayer de changer l'ordre de la table en entrée de FASTCLUS. Ainsi les points de départ dans la construction des classes seront différents, et les classes finales également.
Bonjour,
Je désire effectuer une CAH sous sas avec la PROC FASTCLUS suivi de la PROC CLUSTER car ma base de données est volumineuse. J'aimerai savoir s'il existe une option permettant de fixer le nombre minimum d’individus acceptés dans chacune des classes afin de ne pas se retrouver avec des classes comportant 10 individus et une autre 5000.
Bonjour.Dans l'instruction PROC FASTCLUS, vous avez une option DELETE= derrière laquelle vous pouvez indiquer la taille minimale d'une classe.
J'ai besoin de faire une classification sur des individus décrits par des variables discrètes. Est-ce qu'il me suffit de travailler sur des indicatrices de ces variables ?
Il serait plus correct d'alimenter la procédure de classification (proc CLUSTER ou FASTCLUS ou les deux) avec les sorties (coordonnées sur les axes factoriels) d'une Analyse des Correspondances Multiples (ACM réalisée avec la proc CORRESP). Comme la proc CORRESP attend un tableau disjonctif complet, on l'alimente effectivement avec des indicatrices. On récupère ensuite les coordonnées des individus sur les axes factoriels avec l'option OUT. Ces coordonnées sont des variables quantitatives : on peut donc les utiliser dans les procs CLUSTER et FASTCLUS.
Bonjour, je suis en stage et je voudrais réaliser un arbre de décision sous SAS. Je voudrais connaître la forme du programme permettant de construire un arbre de décision sous SAS. Merci d'avance
Il n'existe malheureusement pas de programme existant directement dans SAS pour réaliser des arbres de décision. Ceux-ci peuvent être produits avec l'interface SAS Enterprise Miner, qui fait l'objet d'un module facturé en sus.
A partir de SAS 9.4, on peut cependant produire des arbres de décision avec la procédure HPSPLIT de SAS/STAT.
Je me pose des questions sur la sélection de variables sous SEM : en effet le test du chi-deux proposé ne semble pas correspondre au test du chi-deux sous SAS (PROC FREQ avec option CHISQ). Qu'en est-il vraiment? je suis allée voir ce que faisait SEM dans le Program Editor et il fait une PROC DMSPLIT : qu'est-ce que c'est que cette PROC ? Dans quel module est-elle disponible ?
En fait, le noeud VARIABLE SELECTION construit un arbre comme le noeud TREE (d'où la proc DMSPLIT qui est en fait celle qui tourne derrière TREE), sur la base de l'algorithme CHAID. Les variables retenues sont donc celles qui sortent les premières dans l'arbre. Cependant, il ne faut pas non plus espérer retrouver exactement le même arbre qu'avec le noeud TREE (hé non, ce serait trop simple !!!), sauf à ne pas avoir de valeurs manquantes dans les données (le noeud VARIABLE SELECTION traite les valeurs manquantes différemment de TREE).
proc corresp data=stage.basefinale outc=corr; tables Nom_DRD naf cible effectif_consolide2 nb_etablissement2 chiffre_affaire2 libelle_Forme_Juridique_Prospect Departement_prospect ; run;Mes questions sont les suivantes : Est-ce que l'ACM effectué ci-dessus est bonne? Et sur quels résultats exactement dois-je réaliser l'analyse discriminante (inertie, mass, dim,....)? Merci d'avance ! Bonjour. Pour pouvoir enchaîner ACM et analyse discriminante, il faut réaliser l'ACM dans l'espace des individus. Or l'instruction TABLES ne permet de se placer que dans l'espace des variables. Vous devez plutôt utiliser l'instruction VAR, et mettre en entrée une table d'indicatrices (à créer avec la procédure Transreg par exemple). Vous trouverez sur notre site une macro SAS pour faire un modèle DISQUAL.
Bonjour, Voilà mon souci : je voudrais faire une Classification sur une énorme base (env 2 millions de lignes). Ce sont des données qualitatives, alors je dois passer par une ACM, donc construire un Tableau Disjonctif Complet (en tout j'ai 3 variables et 11*97*18 modalités). Seulement SAS bloque un peu beaucoup (il a mouliné toute la nuit et n'a pas avancé...)! La proc transreg que vous proposez dans cette FAQ n'est-elle pas appropriée ici? Ma base est-elle trop volumineuse pour un tel traitement? Si oui, comment faire ma classification? Merci beaucoup pour votre éclairage!
Deux pistes à explorer pour que votre traitement puisse se faire dans un temps acceptable (et, vu vos volumes, se faire tout court !).
1) travailler uniquement sur un échantillon : au lieu des 2 millions de lignes, vous pourriez construire une typologie sur seulement 10% d'entre eux, et ensuite chercher les règles de construction des classes (par un modèle statistique, ou plus simplement par une caractérisation univariée) pour dispatcher l'ensemble de vos lignes dans les différentes classes. 2) réduire le nombre de modalités d'une de vos valeurs : 97 valeurs me paraît un nombre un peu excessif. D'autant que cela risque de déséquilibrer fortement l'ACM (les premiers axes se concentreront sur l'information contenue dans cette variable et pas dans les 2 autres) Vous pourriez faire un recodage pour vous ramener à une vingtaine de valeurs ; non seulement ça équilibre l'ACM, mais en plus la taille des fichiers à traiter (tableau disjonctif complet en entrée de la procédure Corresp, et le tableau de Burt qu'elle construit en interne) sera plus raisonnable. Comment faire votre recodage ? Déjà sur des critères métier, je pense. Et également en faisant une ACM sur cette variable uniquement, dans l'espace des variables seulement, de préférence sur un échantillon aléatoire de vos deux millions de lignes. Pour cette ACM préalable, la syntaxe SAS est la suivante :PROC CORRESP DATA = votreTableSAS MCA SHORT ; TABLES votreVariableA97Modalites ; RUN ;
Si vous avez une version 9 de SAS, vous pouvez ajouter les deux instructions suivantes avant la procédure correspondante :
ODS GRAPHICS ON ; ODS HTML FILE = "c:\temp\sorties ACM.htm" GPATH = "c:\temp" (URL=NONE) ; Et ODS HTML CLOSE ;
après l'instruction RUN ; à la fin du programme.
Non seulement vos sorties seront plus jolies dans une page Web (changer éventuellement c:\temp pour un autre répertoire dans les deux options qui y font référence) mais en plus ODS GRAPHICS ajoutera directement le premier plan factoriel dans l'espace des variables : il ne vous reste "qu'à" fusionner les modalités qui sont proches dans ce plan.PROC PLOT DATA = tableSAS ; PLOT varY * varX = "#" $ variableTexte ; RUN ; QUIT ;Le signe # sert de marqueur aux points (il peut être remplacé par ce que l'on veut) et variableTexte contient les noms de modalités, identifiants d'individus, etc. A noter qu'à partir de la version 9.1 de SAS, ODS GRAPHICS produit le 1er plan factoriel d'une AFC avec la procédure CORRESP. En revanche, il nécessitera SAS/GRAPH en version 9.2 (et redevient dans SAS/Base à partir de SA 9.3 !!!).
Bonjour.
Je veux faire une classification sur les individus d'un tableau disjonctif complet. Pouvez-vous me donner le code sous SAS ? D'avance merci.
Bonjour.Comme votre point de départ est un tableau disjonctif complet, il est préférable de faire une ACM (PROC CORRESP) au préalable. On récupère les coordonnées factorielles des observations dans la table créée par l'option OUTC de la PROC CORRESP (filtrer uniquement les lignes où _TYPE_="OBS"). La procédure CLUSTER construit ensuite une CAH sur les coordonnées factorielles :
PROC CLUSTER DATA = tableSAS OUTTREE = tableDendogramme ; VAR dim: ; RUN ;La table créée par l'option OUTTREE contient les informations nécessaires au dessin du graphique de fusion des classes (dendogramme ou graphique arborescent). On obtient ce dernier par la procédure TREE :
PROC TREE DATA = tableDendogramme ; RUN ;Une fois choisi le bon nombre de classes, vous exécutez une dernière fois la procédure TREE pour obtenir l'affectation des individus aux classes :
PROC TREE DATA = tableDendogramme OUT = tableClassement NCLUSTERS = nbClasses ; RUN ;
Bonjour. Que vous ayez deux, trois ou deux cents variables à inclure dans l'ACM n'est pas source de différences dans le programme SAS. Si vous partez d'une table SAS qui est déjà un tableau disjonctif complet, c'est assez simple. Si ce n'est pas le cas, vous pouvez construire un TDC avec la procédure TRANSREG. La procédure CORRESP utilise la syntaxe suivante :
PROC CORRESP DATA = tableau_disjonctif_complet
NOROW=PRINT OUTC = tableSAS_sortie ;
VAR listeVariablesIndicatricesDuTDC ;
RUN ;
Deux remarques :
1) NOROW=PRINT est une option conseillée si vous travaillez sur un nombre important d'observations, elle évite l'édition dans la fenêtre OUTPUT des coordonnées factorielles, cosinus et autres qualités de chaque observation ;
2) si vous avez construit le TDC avec la procédure TRANSREG, la liste des variables indicatrices à spécifier dans VAR est : VAR &_trgind ;
Bonjour, Comment savoir si on doit réaliser un AFC ou une ACP sur un jeu données. Est-ce que SAS est capable de faire le choix tout seul ou y a-t-il un moyen d' effectuer une ACP ou une AFC avec SAS? Merci
Pour choisir, un moyen simple : les ACP se font sur des données exclusivement continues (quantitatives) et les AFC et ACM sur des données discrètes (qualitatives). Si vous avez des variables des deux types, le plus simple est de mettre en tranches les variables quantitatives et de faire une AFC du tout.
SAS ne fait pas le choix pour vous mais propose deux procédures : PRINCOMP pour les ACP, et CORRESP pour les AFC et ACM. Les sorties de ces deux procédures sont assez limitées en intérêt, aussi est-il souvent nécessaire d'enchaîner une série de procédures graphiques pour obtenir des beaux résultats (axes factoriels, projection des individus et des variables dans les plans factoriels, ...).
N'hésitez donc pas à vous intéresser aux tables produites par ces deux procédures (options OUT= et OUTSTAT=) qui vous permettront ensuite d'enchaîner les traitements pour avoir des résultats exploitables.
Score
- soit vous avez peu de contrats auto récents (mettons quelques centaines seulement) et il faudra probablement ouvrir un petit peu la plage temporelle pour construire une base d'étude avec, au moins, un millier de contrats auto, et un millier de clients n'en ayant pas ;
- soit vous avez déjà, avec les nouveaux clients auto des deux années écoulées, des volumes suffisants, et le risque d'aller chercher les clients plus anciens serait de prendre un compte un profil qui n'est plus ceux des clients qui vous rejoignent actuellement. (Pour des raisons d'évolution de tarifs, de concurrence, d'image, de campagne publicitaire, ceux qui ont souscrit il y a, mettons, 5 ans, ne le feraient peut-être plus chez vous aujourd'hui, et ne restent que par inertie.)
- choisir un seuil pour transformer les prédictions continues (le score) en prédictions binaires (par exemple : 0,5 : si P_1 < 0,5 alors Ypredit = 0, sinon Ypredit=1)
- calculer la nouvelle variable binaire Ypredit
- la croiser (dans une proc Freq) avec la variable Yobservé
- additionner les pourcentages (2e ligne de chaque case) des cellules dans la diagonale du tableau (correspondances entre Yobservé et Y prédit).
- Dans la partie Fit Statistics, on retrouve les critères d'Akaike, de Schwartz et la log-vraisemblance
- Dans la partie Global Tests, on a les tests du chi2 associés au score, à la log-vraisemblance et à la statistique de Wald
OUTPUT OUT = table PRED = variableP ;on a dans variableP les valeurs prédites pour les données inconnues (ce qu'on appelle un score). Ces valeurs s'échelonnent de 0 à 1, on les lit comme des probabilités d'occurrence d'un évènement. A partir de SAS 9.3, on peut aussi utiliser l'instruction SCORE.
ODS OUTPUT parameterEstimates = work.coeffs ;et vous retrouverez dans la table COEFFS de la bibliothèque WORK vos coefficients.
En faisant une modélisation sur SEM avec des réseaux de neurones, on obtient un taux de mal classés de 50% : alors, que doit-on faire ? Arrêter ?
Augmenter la taille de la couche cachée pourrait être une solution. Une deuxième couche cachée n'est utile que si vous avez des relations très très très complexes entre les entrées et les sorties. Sinon, on peut essayer en bougeant la limite du score : par défaut, il décide dans un sens ou dans l'autre autour de la valeur bascule de 0,5. Peut-être qu'on aurait moins de mal classés en décalant cette limite, ou en créant une zone d'incertitude (zone de non-décision).
Je ne trouve pas la même note de score que SEM lors de la régression... En fait moi je considère que quand par exemple sur une variable à 2 modalités l'individu a la modalité 2 le coefficient de cette modalité 2 est égal à zéro alors que SEM prend comme coeff -(le coeff de la modalité 1)... Exemple pour la variable détention de sécurité12, on a 2 modalités sec1 et sec2.. Sur la grille des coefficients, le coeff de sec1=0.23 et dans ce cas si un individu a la modalité 2, SEM va lui mettre un coeff de -0.23 alors que moi je lui mettrais zéro... Ma question est : de quelle théorie sort-il cette règle? et qu'est ce que ça change et qui a raison?
Il s'agit d'une des petites subtilités du noeud régression : il fonctionne selon deux types de codage, donc d'évaluation des paramètres... Le premier, appelé DEVIATION, est celui par défaut. Il contraint la somme des paramètres à faire toujours 0, d'où l'obligation de prendre l'opposé comme coefficient du niveau de référence quand on a une variable binaire. Le second modèle de codage, GLM, est celui qu'on a l'habitude de manipuler. (Y compris dans les procédures REG et LOGISTIC.) Il consiste à mettre 0 pour la modalité de référence, et à donner les autres coeffs en fonction. Comme toujours, sur les fondements théoriques de leurs implémentations, les docs SAS restent d'une louable discrétion. En revanche, comment se débarrasser de ce codage bizarre ? Il suffit de cocher la case INPUT CODING = GLM au lieu du défaut INPUT CODING = DEVIATION. Cela se passe dans l'onglet MODEL OPTIONS, sous-onglet REGRESSION, dans le paramétrage de ce noeud.
Comment est ce que je peux récupérer facilement la note du score créé par SEM pour chaque client ?
La note de score de chaque individu se trouve dans les variables P_EVENT, P_NEVENT, P_variableCibleModalité1, P_variableCibleModalité2, etc... (ces derniers noms sont bien sûr tronqués sur 8 ou 32 caractères selon la version de SAS). C'est entre 0 et 1. On trouve cette info une fois fait le scoring, of course, dans la table scorée. Si c'est vous qui avez lancé l'étape Data de scoring (dans le program editor), vous savez le nom de cette table. Si c'est SEM qui a tout fait (noeud Score ! [apply]), c'est dans la table correspondant au contenu de la macro-variable _SCORE. On peut connaître ce contenu en faisant %put &_score ; dans le program editor, et le nom de la table appraîtra dans la log. Reste à l'ouvrir classiquement (proc print, fenêtre Explorer, FSView).
Suite à une modélisation de variable binaire, j'utilise la PROC LOGISTIC de SAS 8.2. - Pour espérer obtenir de meilleurs résultats, faut-il équilibrer ma population de clients et de non clients? Exemple: expliquer une situation Y=1 alors que 80% de la population étudiée a Y=1, donne-t-il un poids trop important à ce groupe de clients ? - L'équilibre doit-il se faire dans l'échantillon d'apprentissage (70% de la population totale) sans s'en occuper dans l'échantillon test? - Après avoir obtenu les coefficients estimés du modèle sur les variables explicatives significatives dans le journal via la procédure ou sous EM, comment puis-je appliquer ce modèle sur une autre population (présentant évidemment les mêmes variables explicatives) afin de tous les attribuer un score? Suis-je obligée de faire cette étape manuellement ? Merci beaucoup de votre aide.
Il est toujours préférable de travailler sur un échantillon équilibré. Pour pouvoir comparer les performances de votre modèle sur le corpus d'apprentissage et sur celui de test, il est préférable que les deux soient équilibrés.
L'utilisation des coefficients du modèle peut se faire via la procédure SCORE si les variables explicatives de votre modèle sont quantitatives, ou des indicatrices. La prise en compte par la proc SCORE des variables quali est très mauvaise. Sinon, il est possible d'effectuer automatiquement ces manipulations en écrivant un petit macro-programme.
A noter qu'à partir de la version 9, la proc LOGISTIC intègre une instruction pour préciser une table SAS à scorer.
Dans SEM, un point me pose problème : est ce qu'il a moyen de prendre comme critère le fait de maximiser le taux de détention=1. Je m'explique: en fait le score que j'ai obtenu a un bon taux global mais en fait je me suis rendue compte que peu de gens avaient une note de score élevé ce qui correspondrait au fait que le taux de détention=0 bien classés est supérieur à celui de détention=1 alors que j'aimerais favoriser le 2ème taux...
Pour ce problème, en fait, il faut imposer au modèle une matrice de coûts et profits qui met en avant l'importance de modéliser et bien scorer les détenteurs plutôt que les non-détenteurs. L'autre solution consiste à équilibrer l'échantillon (autant de détenteurs que de non-détenteurs).
Quand je spécifie une probabilité a priori (Prior proba) dans un noeud Tree, il prend cette proba pour l'échantillon d'apprentissage, de validation et de test. Or moi, ce que je voudrais, c'est qu'il prenne cette proba pour apprendre et qu'il valide et teste sur un échantillon normal. A part dupliquer les individus à qui je veux donner une plus grande importance, comment résoudre ce problème ?
Pas de possibilité (connue de nous au moins) de n'appliquer les probas a priori qu'à l'échantillon d'apprentissage. En fait, ces probas sont considérées comme des coûts (matrice de coût et profit) qui s'appliquent tout le temps. Par contre, l'aide (EM Reference dans le menu Help de SEM) est assez détaillée sur le rôle de ces probas, en plus y a de fort belles images.
Je ne suis pas sûr de bien comprendre ta question, mais s'il s'agit de faire un score il suffit de laisser travailler le noeud "Score !". Il génère une étape Data qui retrace les différentes branches de l'arbre. Sinon, le score (la proba) est calculé comme le pourcentage d'évènements dans la feuille de l'arbre considérée.
proc corresp data=stage.basefinale outc=corr; tables Nom_DRD naf cible effectif_consolide2 nb_etablissement2 chiffre_affaire2 libelle_Forme_Juridique_Prospect Departement_prospect ; run;Mes questions sont les suivantes : Est-ce que l'ACM effectué ci-dessus est bonne? Et sur quels résultats exactement dois-je réaliser l'analyse discriminante (inertie, mass, dim,....)? Merci d'avance ! Bonjour. Pour pouvoir enchaîner ACM et analyse discriminante, il faut réaliser l'ACM dans l'espace des individus. Or l'instruction TABLES ne permet de se placer que dans l'espace des variables. Vous devez plutôt utiliser l'instruction VAR, et mettre en entrée une table d'indicatrices (à créer avec la procédure Transreg par exemple). Vous trouverez sur notre site une macro SAS pour faire un modèle DISQUAL.
Séries temporelles
- la proc ARIMA a une option FORECAST (avec une option LEAD pour indiquer le nombre de périodes pour lesquelles calculer des valeurs) pour créer une table de prévisions
- vous pouvez mettre en œuvre l'équation de prévision dans une étape Data : l'observation à t-1 s'obtient avec la fonction LAG, t-2 avec LAG2, etc., à condition que les observations soient triées par ordre chronologique.
proc arima data=a.s1; identify var=prod(1,12) nlag=24 noprint; estimate q=(1)(12) ; run; quit;ou
proc arima data=a.s1; identify var=prod(1,12) nlag=24 noprint; estimate q=(1)(12) Q=(1)(12) ; run; quit;??? merci Bonjour. On suppose qu'on cherche à estimer un processus SARIMA (p,d,q)(P,D,Q)s. Dans l'instruction ESTIMATE vous devez indiquer P,p, Q et q, avec une syntaxe qui défie un peu la logique : ESTIMATE P=(p)(P) Q=(q Q) ; En revanche, comme SAS ne fait pas de différence entre minuscules et majuscules en dehors des chaînes entre guillemets, peu importe qu'on écrive P= et Q= ou p= et q=. Pour la différentiation et la saisonnalité, c'est l'instruction IDENTIFY qui les décrit, comme dans votre exemple : VAR=série(d,s*D).
Valeurs manquantes
- de filtrer les données en amont avec un WHERE
- d'utiliser un format pour associer les valeurs des valeurs des variables CLASS à ne pas afficher avec des valeurs manquantes (par défaut, la procédure Tabulate n'affiche pas les valeurs manquantes)
Généralement (sauf dans le noeud "Arbre de Décision"), les observations comportant au moins une valeur manquante sont exclues de l'analyse. On peut choisir de les compléter au préalable avec le noeud Replacement, ou avec un noeud SAS Code faisant appel à la PROC MI. Dans le noeud Arbre de Décision, on peut utiliser la valeur manquante comme une valeur à part entière, ou exclure les observations incomplètes comme dans les autres modèles. Pour cela, dans l'onglet BASIC, on coche (ou pas) TREAT MISSING AS AN ACCEPTABLE VALUE.
Dans SEM, les valeurs manquantes ne sont pas traitées, sauf cas exceptionnel, comme des valeurs ordinaires. Tous les codages de la variable cible sont autorisés, sauf ceux qui incluent une valeur manquante.
Versions de SAS
LIBNAME lib6 V6 "répertoire" ; LIBNAME lib8 V8 "répertoire" ; LIBNAME tout (lib6 lib8) ;Pour la conversion, sinon, après la définition de lib6 et lib8 comme ci-dessus, il est possible de transformer les tables d'une version à l'autre par une simple PROC COPY. Attention ! Il est certainement préférable de transformer une table v6 en table v8 que l'inverse (parfois impossible si un nom de variable dépasse 8 caractères, ou un label 32 signes, etc...).
Nom_complet = TRIM(prenom)!!" "!!TRIM(nom) ;Ou, en SAS v9, utiliser la fonction STRIP (suppression des blancs à gauche et à droite), ou encore les fonctions CATT (concaténation et suppression des blancs à droite) ou CATX (concaténation, élimination des blancs à gauche et à droite, insertion d'un caractère séparateur) :
Nom_complet = CATX(" ", civilite, prenom, nom) ;
OUTPUT OUT = table PRED = variableP ;on a dans variableP les valeurs prédites pour les données inconnues (ce qu'on appelle un score). Ces valeurs s'échelonnent de 0 à 1, on les lit comme des probabilités d'occurrence d'un évènement. A partir de SAS 9.3, on peut aussi utiliser l'instruction SCORE.
- faire précéder le programme de l'option système VALIDVARNAME=ANY qui va autoriser les caractères accentués dans les noms.
- Faire un RENAME dès que possible pour se débarrasser de l'accent et pouvoir repositionner VALIDVARNAME à sa valeur initiale, V7.
OPTION VALIDVARNAME=ANY ; ODS OUTPUT crossTabFreqs = work.maSortie (RENAME = ("Fréquence"n = Frequence)) ; PROC FREQ DATA = ... ; TABLE ... ; RUN ; OPTION VALIDVARNAME=V7 ;
data ww.CMb; set ww.CM1b ww.CM2b ... ww.CM40b; run;Merci Bonjour, et merci de votre question. Vous pouvez utiliser un programme comme celui-ci :
%MACRO empilement (nbTables) ; DATA ww.CMb ; SET %DO i=1 %TO &nbTables ; ww.CM&i.b %END ; ; RUN ; %MEND empilement ;
%empilement (40)A partir de SAS 9.2, plus besoin de macros ! Vous pouvez écrire directement
SET ww.CM1-ww.CM40 ;dans votre étape Data. Par contre, comme dans votre cas le nom des tables ne se termine pas par un nombre, il faudra rester à la solution macro.
LIBNAME fichier6 V6 '/user/chemin/rep' ; LIBNAME fichier8 '/user/chemin/rep' ; PROC COPY IN = fichier6 OUT = fichier8 ; RUN ;Autre possibilité, vous pouvez télécharger gratuitement depuis Internet le SAS Viewer (il est aussi sur les CD d'installation, demandez aux informaticiens) qui devrait permettre d'ouvrir la table Unix et de l'enregistrer sous... soit directement le format SAS7BDAT Windows v8 - v9, soit au pire en fichier plat .CSV et vous devrez refaire un import puis remettre les labels.
PROC FORMAT ; PICTURE milliers (ROUND) 0 - HIGH = "000 000 009" ; RUN ;Vous utilisez ensuite le format milliers. quand vous en avez besoin. Pour plus d'informations sur les formats "picture", voir Les pictures expliqués à ma fille.
- soit la création de classeurs au format XML si tu as Excel 2003 ou plus récent pour les relire (il y a des macros en ce sens sur Internet, par exemple sur le site de Richard deVenezia) ;
- soit avec SAS PC et un lien DDE (écriture "en live" vers une feuille Excel déjà ouverte)
- pour toutes versions de SAS depuis la 8.0, vous pouvez ouvrir une destination ODS HTML sur le même principe qu'ODS RTF, en indiquant dans FILE= un fichier dont l'extension est .XLS. Vous ne créerez pas une feuille Excel au sens strict, mais une page Web qu'Excel sait lire à partir de la version 1997
- pour SAS 9.1 et Excel 2003 minimum, vous pouvez utiliser ODS TAGSETS.EXCELXP qui va créer un (presque) véritable classeur Excel. La documentation sur cette destination et ses options peut s'afficher dans la fenêtre Log en exécutant le programme suivant :
ODS TAGSETS.EXCELXP OPTIONS(DOC="help") FILE = "c:\temp\rien.xls" ;
- pour SAS 9.4 et Excel 2007 minimum, vous pouvez utiliser ODS EXCEL qui va créer un véritable classeur Excel d'extension XLSX.
Bonjour, J'essaye d'utiliser la fonction week dans mon programme, pour convertir une date en découpage hebdo. Il semble que cette fonction ne soit pas reconnue. Je suis actuellement en SAS V8, est-ce que cette fonction n'est dispo qu'en V9 ? Je vous remercie pour vos réponses. Bonne journée !
Bonjour. Effectivement la fonction WEEK est nouvelle avec la version 9. A l'utilisation, elle nécessite un 2e argument, "V" ou "W" pour indiquer le mode de calcul des numéros de semaine. Les semaines commencent le lundi et la semaine n°1 commence au 1er lundi de janvier. Les jours précédant le 1er lundi de janvier appartiennent à la semaine 52 si on indique "V", ou la semaine 0 avec "W".
En version 8, vous devez utiliser la fonction INTCK qui calcule le nombre de lundis entre 2 dates (WEEK.2 désigne des semaines commençant le lundi) : semaine=INTCK("WEEK.2", MDY(1,1,YEAR(maDate)), maDate) ; Avec cette formule, les jours précédant le 1er lundi de janvier appartiendront à la semaine 0.Bonjour, je suis en stage et je voudrais réaliser un arbre de décision sous SAS. Je voudrais connaître la forme du programme permettant de construire un arbre de décision sous SAS. Merci d'avance
Il n'existe malheureusement pas de programme existant directement dans SAS pour réaliser des arbres de décision. Ceux-ci peuvent être produits avec l'interface SAS Enterprise Miner, qui fait l'objet d'un module facturé en sus.
A partir de SAS 9.4, on peut cependant produire des arbres de décision avec la procédure HPSPLIT de SAS/STAT.