2017-03-31 2 views
1

Je dois générer beaucoup de jeux de données différents dans différents fichiers texte. Les ensembles de données partagent certaines variables communes qui doivent être produites, mais en ont également beaucoup d'autres différentes. J'ai chargé ces différents dans une variable de macro séparée par des blancs afin que je puisse macroiser ceci. J'ai donc créé une macro qui boucle sur les jeux de données et les sort dans un fichier texte différent. Pour cela, j'ai utilisé une instruction put à l'intérieur d'une étape de données. La déclaration PUT ressemble à ceci:Sortie vers un fichier texte

PUT (all the common variables shared by all the datasets), (macro variable containing all the dataset-specific variables); 

.: par exemple

%MACRO OUTPUT(); 
    %DO N=1 %TO &TABLES_COUNT; 
     DATA _NULL_; 
      SET &&TABLE&N; 
      FILE 'PATH/&&TABLE&N..txt'; 
      PUT a b c d "&vars"; 
     RUN; 
    %END; 
%MEND OUTPUT; 

Où & vars est la variable macro contenant toutes les variables nécessaires pour produire un ensemble de données dans la boucle de courant. qui obtient résolu, par exemple, à:

PUT a b c d special1 special2 special5 ... special329; 

Maintenant, le problème est, la chaîne entre guillemets ne peut être 262 caractères. Et certains de mes ensembles de données que j'essaie de produire ont tellement de variables à sortir que cette variable macro qui est une chaîne entre guillemets et qui contient toutes ces variables sera beaucoup plus longue que cela. Y a-t-il un autre moyen de faire ça?

+1

Je ne pense pas qu'il y ait une limite au nombre de variables qu'une instruction PUT peut référencer. Mais pourquoi avez-vous des virgules au milieu de votre déclaration PUT? – Tom

+0

Suppression des virgules et modification de la question. Merci d'avoir signalé! – puk789

+0

Les cotations ne sont pas non plus nécessaires ... – Joe

Répondre

1

J'aborderais cela mais avec 1 instruction put par variable. Utilisez le modificateur @ pour ne pas avoir de nouvelle ligne.

Par exemple:

data test; 
a=1; 
b=2; 
c=3; 
output; 
output; 
run; 

data _null_; 
set test; 
put a @; 
put b @; 
put c @; 
put; 
run; 

Sorties ce dans le journal:

800 data _null_; 
801 set test; 
802 put a @; 
803 put b @; 
804 put c @; 
805 put; 
806 run; 

1 2 3 
1 2 3 
NOTE: There were 2 observations read from the data set WORK.TEST. 
NOTE: DATA statement used (Total process time): 
     real time   0.07 seconds 
     cpu time   0.03 seconds 

modifier votre macro donc en boucle à travers les deux ensembles de valeurs en utilisant cette syntaxe.

+0

Suppression des virgules et modification de la question. Merci d'avoir signalé! – puk789

2

N'incluez pas de guillemets autour de la liste des noms de variables.

put a b c d &vars ; 

Il ne devrait pas y avoir de limite au nombre de variables vous pouvez produire, mais si la longueur de la ligne de sortie est trop longue SAS termineront à une nouvelle ligne. La longueur de ligne par défaut est actuellement de 32 767 (mais les anciennes versions de SAS utilisent 256 comme longueur de ligne par défaut). Vous pouvez réellement définir cela beaucoup plus haut si vous voulez. Vous pouvez donc utiliser 1 000 000 par exemple. La limite supérieure dépend probablement de votre système d'exploitation.

FILE "PATH/&&TABLE&N..txt" lrecl=1000000 ; 

Si vous voulez juste vous assurer que les variables communes apparaissent à l'avant (qui vous n'excluez pas l'une des variables) alors peut-être que vous n'avez pas besoin la liste des variables pour chaque table du tout .

DATA _NULL_; 
    retain a b c d ; 
    SET &&TABLE&N; 
    FILE "&PATH/&&TABLE&N..txt" lrecl=1000000; 
    put (_all_) (+0) ; 
RUN; 
+0

Suppression des virgules et modification de la question. Merci d'avoir signalé! – puk789

1

Je ne sais pas pourquoi vous parlez de chaînes entre guillemets: vous ne citerais pas l'argument & vars.

put a b c d &vars; 

pas

put a b c d "&vars"; 

Il y a une limite là, mais il est beaucoup plus élevé (64k).

Cela dit, je le ferais d'une manière axée sur les données avec CALL EXECUTE. Ceci est assez simple et fait tout en une seule étape, en supposant que vous pouvez facilement déterminer quels jeux de données à produire à partir des tables de dictionnaire dans une instruction WHERE. Cela a une limite de 32kiB totale, mais si vous allez en faire plus, vous pouvez contourner cela très facilement (vous pouvez séparer plusieurs bits en plusieurs appels, et même structurer l'appel de sorte que si le callstr atteint 32000 vous lancez un appel avec lui, puis continuez).

Cela évite d'avoir à gérer un tas de grandes variables macro (votre &VAR sera vraiment &&VAR&N et sera beaucoup de grandes variables macro).

data test; 
    length vars callstr $32767; 
    do _n_ = 1 by 1 until (last.memname); 
    set sashelp.vcolumn; 
    where memname in ('CLASS','CARS'); 
    by libname memname; 
    vars = catx(' ',vars,name); 
    end; 
    callstr = catx(' ', 
    'data _null_;', 
    'set',cats(libname,'.',memname),';', 
    'file',cats('"c:\temp\',memname,'.txt"'),';', 
    'put',vars,';', 
    'run;'); 
    call execute(callstr); 
run;