Voici une requête SQL hypothétique dans SAS. Ce tableau contient une colonne de mots commençant par A, B et C.J'ai créé une macro variable avec ces valeurs séparées par des virgules et je souhaite générer un rapport contenant uniquement des mots dont la première lettre est B.
%let Letter=A, B, C; proc sql; select * from Words where Letter = %scan("&Letter", 2, ","); quit;
Pour une raison quelconque, j'obtiens ce qui suit: "ERREUR: Les colonnes suivantes n'ont pas été trouvées dans les tableaux contributifs: B"
Pourquoi l'instruction WHERE rechercherait-elle une colonne nommée B, au lieu de produire un rapport de toutes les lignes dont la première lettre d'un mot est B?
Merci d'avance!
3 Réponses :
Je ne sais pas comment faire fonctionner cela avec des macros, mais en SQL, cela ressemblerait à:
select w.* from Words w where w.word LIKE 'A%' or w.word LIKE 'B%' or w.word LIKE 'C%' ;
Des moyens probablement plus faciles de faire fonctionner cela, mais c'est de deux manières. L'une modifie votre approche actuelle et une autre illustre une approche par étapes de données. Si vous utilisez% SCAN (), il renvoie B, qui est une variable. Si vous utilisez SCAN (), il renvoie le caractère "B" à la place, ce que vous voulez. Pour utiliser l'option LIKE, j'ajoute le% à la fin de la chaîne pour indiquer que commence par B. Vous pouvez également utiliser SUBSTR () pour obtenir le premier caractère et le comparer seul.
SCAN renvoie également "B", j'ai donc ajouté une bande pour supprimer les espaces supplémentaires. Je pense qu'il existe une option dans SCAN () pour supprimer les espaces, si vous souhaitez supprimer la fonction STRIP ().
data words; input Letter $12.; cards; Apple Bananas Pears Bread Buffalo Demo Help Suprprise ;;;; %let Letter=A, B, C; proc sql; select * from Words where Letter like catt(strip(scan("&letter", 2, ",")), '%'); quit; proc print data=words; where letter =: strip(scan("&letter", 2, ",")); run;
Le processeur de macros SAS est utilisé pour générer du texte qui est ensuite transmis à SAS pour s'exécuter comme s'il s'agissait du texte original du programme. Vous avez utilisé la fonction macro% SCAN () pour générer le texte B à une position où SAS attendait un nom de variable. Le message d'erreur indique qu'il n'a pas pu trouver la variable B parce que vous lui avez demandé d'utiliser la variable B.
Avant d'utiliser le code de macro pour générer un programme, assurez-vous de savoir quel programme vous voulez générer. Alors peut-être voulez-vous générer la déclaration:
%let list=A|B|C; select * from Words where Letter like "%scan(&letter,2,|)%" ;
Cela trouvera toutes les observations dans MOTS où la variable LETTER commence par une majuscule B.
Pour générez cela à partir de votre macro variable (également nommée LETTER), vous pouvez utiliser un code comme celui-ci:
select * from Words where Letter like " B%" ;
Notez que votre exemple de valeur LETTER ne générera pas réellement ce que vous voulez. Au lieu de cela, cela générera ce code:
select * from Words where Letter like "%scan(&letter,2,%str(,))%" ;
qui recherche les valeurs commençant par un espace puis la majuscule B. C'est parce que vous avez inclus un espace après la virgule. P >
Il est beaucoup plus facile d'utiliser un délimiteur autre que la virgule lors de l'insertion d'une liste de valeurs dans une variable macro. Par exemple, vous pouvez utiliser le caractère |
.
select * from Words where Letter like "B%" ;
Veuillez afficher le journal complet, y compris le message d'erreur. Et essayez SCAN () au lieu de% SCAN ().
Quels sont les noms des variables de votre ensemble de données? Vous parlez d'une «colonne» qui contient des «mots». Mais votre code fait référence à un ensemble de données nommé WORDS et à deux variables, l'une nommée LETTER et l'autre nommée B. Montrez des exemples de données et la sortie que vous voulez de ces données.
Écoutez @Tom. Sa sagesse est au service des programmeurs à tous les niveaux de compétence - "Avant d'utiliser le code de macro pour générer un programme, assurez-vous de savoir quel programme vous voulez générer"