Convertir une variable caractère en numérique et inversement

Convertir une variable caractère en numérique et inversement

By : -

Convertir une variable caractère en numérique et inversement

Les datasets sont composés de variables caractères (character) et de variables numériques (numeric). On peut avoir une variable caractère qui ne contient que des nombres et vouloir en faire une variable numérique ou à l’inverse avoir une variable numérique et vouloir stocker l’information sous forme de texte dans une variable caractère. C’est une manipulation très courante. Nous faisons pour cela appel aux fonctions INPUT et PUT.

1. Du caractère au numérique et inversement

La fonction INPUT a besoin de deux informations : le texte (aussi appelé chaîne de caractères) et la règle qui permet de le lire/interpréter correctement. La fonction a donc deux paramètres : le premier paramètre contient soit le nom d’une variable caractère, soit directement la chaîne de caractères entre guillemets. Le second paramètre contient le nom de l’INFORMAT.

Dans l’exemple, on indique qu’il faut lire la variable d’origine comme une variable texte pouvant atteindre une longueur de 11 caractères.

data char_to_num;
   x_char = '12345.12345';
   x_num  = input(x_char,$11.);
  *x_num  = input('12345.123456';,$11.)
  *x_num  = 12345.12345;
run;

2. Du numérique au caractère

Maintenant, nous allons travailler avec une variable numérique qui a 11 chiffres/séparateur dont 6 pour la partie décimale (chiffres + séparateur).

Dans le programme ci-dessous, nous créons une variable caractère de longueur 11 avec la fonction put.

Cette fonction put a deux paramètres : le nom de la variable numérique (ou une valeur numérique) et le format.

Dans l’exemple l’format est 11.5. Cela veut dire lq valeur générée dans la variable caractère peut avoir jusqu’à 11 caractères dont 5 pour la partie décimale (chiffres après le point).

Si la valeur numérique contient plus de 11 caractères, le système cherche pour l’option la moins pire. Il va d’abord réduire le nombre de décimales. Si ce n’est pas exacte, il va réduire les chiffres pour les entiers. I

Une solution alternative à 11.5 est dans ce cas le format best11.. Si aucun nombre n’est indiqué au format best., cela veut dire best8.. Cela veut dire que le système cherches la meilleure réponse possible avec 8 chiffres et un séparateur.

data num_to_char;
   y_num = 123.123;
   output;
   y_num = 12345.12345;
   output;
   y_num = .;
   output;
run;
data num_to_char;
   set num_to_char;
   length y_char1 y_char2 $11;
   y_char1 = put(y_num,11.6);
  *y_char1 = put(y_num,best11.);
  *y_char1 = put(12345.12345,11.6);
  *y_char1 = '12345.12345';
   
   y_char2 = put(y_num,best11.);

   if not missing(y_num) then y_char3=strip(put(y_num,11.6));
run;

Notez la légère différence entre 11.5 et best11. Dans les deux cas des blancs sont ajoutés en début de chaîne. Donc prévoyez une fonction strip pour les enlever.

Par ailleurs, le point des valeurs manquantes numériques est converti en point dans une variable caractère et non en blanc. Pour éviter le problème, on peut appliquer le contenu de manière conditionnelle (if for example).

N’oubliez pas de définir la longueur de votre nouvelle variable caractère au risque de vous retrouver sinon avec du texte coupé.

Pour se souvenir que l’input utilise un informat notez que les deux termes commencent par IN. La fonction put utilise donc un format.

Le petit plus de la fonction put : ajouter des zéros aux extrémités du nouveau texte : le format z. permet de remplacer les espaces vides par des zéros.

Dans l’exemple ci-dessous, la nouvelle variable aura une longueur de 8 caractères. Les deux derniers seront les chiffres après la virgule. Comme il n’y en a qu’un seul dans la variable d’origine, un zéro sera ajouté à la fin. Il reste deux espaces en début à remplir avec des zéros.

data num_char_zero;
    z_num = 123.1;
    length z_char $8;
    z_char = put(z_num,z8.2);
   *z_char = '00123.10';
 run;

3. Passer d’une valeur caractère à une autre variable caractère avec une fonction put

La valeur caractère d’origine peut aussi être du texte et non des nombres. Dans cette situation, la nouvelle variable prend la valeur d’un format caractère souvent défini par le programmeur.

proc format;
   value $cntry
   FR = 'France'
   LU = 'Luxembourg'
   CH = 'Suisse';
 run;
data char_to_char;
   a1_char='LU';
   a2_char=put(a1_char,$cntry.);
   *a2_char='Luxembourg';
 run;

4. La question

Que faire lorsque seulement une partie des valeurs présentent dans la variable correspondent à l’informat utilisé ?

data exemple;
   length x $10;
   x='21JAN2015'; output;
   x='JAN2015';   output;
   x='January';   output;
   x='20150121';  output;
run;

Dans cet exemple, les données contenues dans la variable x sont affichées de manière différentes et toutes ne contiennent pas une date complète. Si j’assume que la seule date correcte est écrite sous la forme DDMMMAAAA alors je peux utiliser le code suivante pour créer une date SAS :

data exemple_erreur;*(where=(input(x,date9.));
   set exemple;
   x_num=input(x,date9.);
run;

Néanmoins, une NOTE s’afficher avec _ERROR_=1 dans la log. Si vous utilisez la fonction input dans l’option where du dataset, alors c’est une ERROR.

NOTE: Invalid argument to function INPUT at line ... column ... 
... _ERROR_=1 _N_=...
ERROR: INPUT function reported 'ERROR: Invalid ... value' while processing WHERE clause.

Pour éviter cela, il suffit d’ajouter deux points d’interrogation devant le nom de l’informat.

data exemple_sanserreur;*(where=(input(x,??date9.));
   set exemple;
   x_num=input(x,??date9.);
run;

Le double point d’interrogation précédent le nom de l’informat empêchera la log d’avoir la note. Bien sûr, cela n’a d’intérêt que si vous avez de bonnes raisons d’ignorer ce message d’erreur. Le cas contraire, vérifiez vos données.

Maintenant pour agrandir le spectre des valeurs valables, vous pouvez rechercher d’autres informats comme anydtdte ou créer le votre.

Avec anydtdte, ce n’est pas seulement 21JAN2015 qui est convertit en date SAS mais également JAN2015 et 20150121. Dans le cas de JAN2015, la date SAS deviendra le 1er janvier 2015. Avec anydtdte, aucun _ERROR_ n’apparaît dans la log.

data exemple_sanserreur;
   set exemple;
   x_num=input(x,anydate.);
   format x_num date9.;
run;

5. Le coin des experts : les fonctions PUTN et PUTC

Voici maintenant un cas utilisé que très rarement mais qui n’en reste pas moins très puissant.

Voici mes données :

data one;
   length test $3 fmt $6 resultat $10;
   test='AAA'; valeur=0;  fmt='NO';     resultat='Non';       output;
   test='AAA'; valeur=1;  fmt='NO';     resultat='Oui';       output;
   test='BBB'; valeur=-1; fmt='INFSUP'; resultat='Inférieur'; output;
   test='BBB'; valeur=0;  fmt='INFSUP'; resultat='Normal';    output;
   test='BBB'; valeur=1;  fmt='INFSUP'; resultat=‘Supérieur'; output;
 run;

L’objectif est d’obtenir la même chose que ce qu’on a dans la variable resultat.

Pour cela nous avons besoin de deux formats numériques : NO et INFSUP donnés dans la variable fmt du dataset one.

proc format;
   value no      0='Non'
                 1='Oui';
   value infsup -1='Inférieur'
                 0='Normal'
                 1='Supérieur';
 run;

A présent, nous utilisons la fonction putn pour créer la variable resultat2. Mais au lieu d’indiquer le nom du format dans la fonction, c’est le nom de la variable qui contient les noms de format qui est utilisée.

data one;
   set one;
   length resultat2 $10;
   resultat2=putn(valeur,fmt);
run;

Le même principe fonction pour la fonction putc. La seule différence est que les formats sont des formats caractères ($).

data two;
   length test $3 valeur $1 fmt $3 resultat $3;
   test='CC'; valeur='N'; fmt='$NY'; resultat='Non'; output;
run;
proc format;
   value $ ny 'N'='Non'
              'Y'='Oui';
run;
data two;
   set two;
   length resultat2 $10;
   resultat2=putc(valeur,fmt);
run;

6. Remarque

Dans un data step, on ne peut pas avoir deux variables du même nom. On peut corriger une variable existante (exemple : diviser par dix pour une variable numérique ou encore garder seulement une partie de la chaîne pour une variable caractère) mais on ne peut pas changer le type ou la longueur d’une variable une fois que ces attributs sont définis.

Pour palier à cela, vous pouvez renommer la variable d’origine pour pouvoir utiliser son nom pour la nouvelle variable et supprimer cette variable d’origine à la fin.

Dans une procédure sql, le même nom peut être utilisé.

data one;
   x=1;
run;
data one (drop=x);
   set one (rename=(x=_x));
   length x $3;
   x='ABC';
run;
2 Comments

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée.

treize − onze =