SAS - поставить пустое место в строке - PullRequest
0 голосов
/ 24 октября 2018

У меня есть скрипт для написания SAS-программы (txt), который выглядит следующим образом:

    /********* Import excel spreadsheet with model sepcs *****************/
    proc import file = "&mydir\sample.xls" out = model dbms = xls replace;
    run;
/********* Create program model *****************/
    data model;         
    set model;          
        dlb = resolve(dlb); 
        dub = resolve(dub); 
    run;                
    data model;
    set model;
        where2 = tranwrd(where,"="," ");
        where2 = tranwrd(where2,"<"," ");
        where2 = tranwrd(where2,">"," ");
        nword = countw(where2);
        bounds = trim(dlb)!!" "!!trim(dub);
        bounds = tranwrd(bounds,"="," "); 
        bounds = tranwrd(bounds,"<"," ");
        bounds = tranwrd(bounds,">"," ");  
        nbounds = countw(bounds);                                 
    run;
proc sql noprint;
    select max(nword) into: max_word from model ;
    select max(nbounds) into: max_aux from model ;                                              
    select name into: list_var separated by " " from dictionary.columns where libname = "WORK" and memname = "IMP" ;
quit;
/******* Generate Model ********/
    %macro generate_model;                                                                                                                          
        data model;                                                                                                                                     
        set model;                                                                                                                                      
        attrib wherev length = $500.;                                                                                                                   
            do i = 1 to countw(where2);                                                                                                                     
                %do j = 1 %to %sysfunc(countw(&list_var));                                                                                                  
                    if upcase(scan(where2,i)) = "%upcase(%scan(&list_var,&j))" and scan(where2,i) not in ("0","1","2","3","4","5","6","7","8","9") then do; 
                        if missing(wherev) then wherev = trim(scan(where2,i));                                                                              
                        else if index(wherev,trim(scan(where2,i))) = 0 then do;                                                                             
                            wherev = trim(wherev)!!" "!!trim(scan(where2,i));                                                                               
                        end;                                                                                                                                
                    end;                                                                                                                                    
                %end;                                                                                                                                       
            end;                                                                                                                                            
        drop i where2;                                                                                                                                  
        run;                                                                                                                                                                                                                                                                                       
        data model;                                                                                                                                     
        set model;                                                                                                                                      
        attrib aux length = $500.;                                                                                                                      
            do i = 1 to countw(bounds);                                                                                                                     
                %do j = 1 %to %sysfunc(countw(&list_var));                                                                                                  
                    if upcase(scan(bounds,i)) = "%upcase(%scan(&list_var,&j))" and scan(bounds,i) not in ("0","1","2","3","4","5","6","7","8","9") then do; 
                        if missing(aux) then aux = trim(scan(bounds,i));                                                                                    
                        else if index(aux,trim(scan(bounds,i))) = 0 then do;                                                                                
                            aux = trim(aux)!!" "!!trim(scan(bounds,i));                                                                                     
                        end;                                                                                                                                
                    end;                                                                                                                                    
                %end;                                                                                                                                       
            end;                                                                                                                                            
        drop i bounds;                                                                                                                                  
        run;                                                                                                                                            
    %mend;                                                                                                                                          
    %generate_model;

data outem.bound;
set outem.model;
attrib txt length = $2000.;
    txt = "******************Macros for variable"!!trim(dep)!!"******;";
    output;
    txt = "%"!!"macro bound"!!trim(dep)!!";";
    output;
    if not missing(lb) then do;
        txt ="LB="!!trim(lb)!!";";
        output;
    end;
    if not missing(ub) then do;
        txt ="UB="!!trim(ub)!!";";
        output;
    end;
    if not missing(dlb) and not missing(lb) then do;
        txt ="LB=MAX(LB,"!!trim(dlb)!!");";
        output;
    end;
    if not missing(dlb) and missing(lb) then do;
        txt ="LB="!!trim(dlb)!!";";
        output;
    end;
    if not missing(dub) and not missing(ub) then do;
        txt ="UB=MIN(UB,"!!trim(dub)!!");";
        output;
    end;
    if not missing(dub) and missing(ub) then do;
        txt ="UB="!!trim(dub)!!";";
        output;
    end;
    txt = "%"!!"mend;";
    output;run;

data outem.imp;
    set outem.bound;
    file "&mydir\3_generate_models\3_model.sas" lrecl = 2000;
    put txt;
run;

Программа работает нормально, однако мне не удается поставить пустое место перед UB или LB.

Вывод выглядит так:

%macro boundHC0340;
LB=           1;
UB=           9;
%mend;

Но я хотел бы получить это:

%macro boundHC0340;
    LB=           1;
    UB=           9;
%mend;

В коде уже есть несколько попыток положить пустойпробел до UB и LB, но пока я не смог справиться.

Я могу поместить туда другие символы и строки.Я просто не могу поставить пустое пространство перед UB и LB, чтобы создать код с отступом.

Я пробовал что-то вроде этого:

txt ="      LB="!!trim(lb)!!";";

Но пустое пространстводо LB ничего не делает.

Однако, если я напишу это:

   txt ="******LB="!!trim(lb)!!";";

Я получу звездочки в моей программе.

Любое представление о том, что мне не хватаетВот?

Большое спасибо за вашу поддержку.

С уважением

Ps: вот гиперссылка на образец файла xls: sample.xls

Ответы [ 2 ]

0 голосов
/ 24 октября 2018

Предполагая, что вы создали переменную TXT со значением, которое хотите увидеть, вам просто нужно добавить формат к вашему последнему шагу.Чтобы избежать написания большого количества бесполезных конечных пробелов, используйте формат $VARYING.Вам нужно будет вычислить длину вашей строки, чтобы использовать этот формат.

data outem.imp;
    set outem.bound;
    file "&mydir\3_generate_models\3_model.sas" lrecl = 2000;
    length= lengthn(txt);
    put txt $varying2000. length;
run;

Но, вероятно, проще просто пропустить все конкатенации и просто использовать силу самого оператора PUT для написания программыпрямо из ваших данных.Затем вы можете использовать такие элементы, как элементы управления указателем (@3) или именованное значение lb= и другие функции оператора PUT для форматирования файла вашей программы.

data _null_;
  set outem.model;
  file "&mydir\3_generate_models\3_model.sas" ;
  put 72*'*' ';'
    / '* Macros for variable ' dep ';'
    / 72*'*' ';'
    / '%macro bound' dep ';'
  ;
  if not missing(lb) then put @3 lb= ';' ;
  if not missing(ub) then put @3 ub= ';' ;
  if not missing(dlb) and not missing(lb) then put
    @3 'LB=MAX(LB,' dlb ');'
  ;
  if not missing(dlb) and missing(lb) then put
    @3 'LB=' dlb ';'
  ;
  if not missing(dub) and not missing(ub) then put
    @3 'UB=MIN(UB,' dub ');'
  ;
  if not missing(dub) and missing(ub) then put
    @3 'UB=' dub ';'
  ;
  put '%mend bound' dep ';';
run;

Хотя, глядя на логику этихЕсли утверждение почему бы не уменьшить их до:

put @3 'LB=MAX(' lb ',' dlb ');' ;
put @3 'UB=MIN(' ub ',' dub ');' ;
0 голосов
/ 24 октября 2018

Я думаю, что это результат того, что SAS применяет выравнивание по левому краю для формата $w. вашей переменной, когда вы используете оператор put.Вы можете переопределить это, применив формат в операторе put и указав, какое выравнивание вы хотите использовать:

data _null_;
  file "%sysfunc(pathname(work))\example.txt";
  a = "       text here";

  /*Approach 1 - default behaviour*/
  /*No leading spaces on this line in output file (default)*/
  put a;


  /*Approach 2 - $varying + right alignment*/
  /*We need to right align text while preserving the number of leading spaces, so use $varying. */
  /*If every line is the same length, we can use $w. instead*/
  /*Use -r to override the default format alignment*/
  varlen = length(a);
  put a $varying2000.-r varlen;

  /*Approach 3 - manually specify indentation*/
  /*Alternatively - ditch the leading spaces and tell SAS which column to start at*/
  put @4 a;
run;

Попробуйте изменить последнюю часть вашего кода, чтобы она выглядела примерно так (исправьте пути и набор данныхимена по необходимости):

data bound;
set model;
attrib txt length = $2000.;
    txt = "******************Macros for variable"!!trim(dep)!!"******;";
    output;
    txt = "%"!!"macro bound"!!trim(dep)!!";";
    output;
    if not missing(lb) then do;
        /* LEADING SPACES ADDED HERE */
        /* LEADING SPACES ADDED HERE */
        /* LEADING SPACES ADDED HERE */
        txt ="    LB="!!trim(lb)!!";";
        output;
    end;
    if not missing(ub) then do;
        /* LEADING SPACES ADDED HERE */
        /* LEADING SPACES ADDED HERE */
        /* LEADING SPACES ADDED HERE */
        txt ="    UB="!!trim(ub)!!";";
        output;
    end;
    if not missing(dlb) and not missing(lb) then do;
        txt ="LB=MAX(LB,"!!trim(dlb)!!");";
        output;
    end;
    if not missing(dlb) and missing(lb) then do;
        txt ="LB="!!trim(dlb)!!";";
        output;
    end;
    if not missing(dub) and not missing(ub) then do;
        txt ="UB=MIN(UB,"!!trim(dub)!!");";
        output;
    end;
    if not missing(dub) and missing(ub) then do;
        txt ="UB="!!trim(dub)!!";";
        output;
    end;
    txt = "%"!!"mend;";
    output;
run;

data _null_;
    set bound;
    file "%sysfunc(pathname(work))\example.sas" lrecl = 2000;
    varlen = length(txt);
    put txt $varying2000.-r varlen;
run;

x "notepad ""%sysfunc(pathname(work))\example.sas""";

Содержимое example.sas (на основе образца xls):

******************Macros for variableHC0340******;
%macro boundHC0340;
    LB=           1;
    UB=           9;
%mend;
...