How to recode variables in table 1 using info from table 2 (in SAS)

后端 未结 3 464
太阳男子
太阳男子 2021-01-26 12:18

The overal goal is to stratify quantitative variables based on their percentile. I would like to break it up into 10 levels (e.g. 10th, 20th, ...100th percentile)

3条回答
  •  长发绾君心
    2021-01-26 12:33

    The following should work for you dynamically with no hard-coding -- I edited to compact it into a single macro. Essentially it puts your desired variables into a list, creates a dataset using your output, and then uses the variable contents to put your data steps into long strings. These strings are then put into a macro variable and you can call it in your final data step. Again, no hard-coding involved.

    %MACRO stratify(library=,input=,output=);
    %local varlist varlist_space data_step_list;
    
        ** get vars into comma-separated list and space-separated list **;
        proc sql noprint;
            select NAME
            into: varlist separated by ","
            from dictionary.columns
            where libname=upcase("&library.") and memname=upcase("&input.");
    
            select NAME
            into: varlist_space separated by " "
            from dictionary.columns
            where libname=upcase("&library.") and memname=upcase("&input.");
        quit;
    
        %percentiles(%bquote(&varlist.)); 
    
        ** put data into long format **;
        proc transpose data = pcts out=pcts_long;
            by recode percentile;
            var &varlist_space.;
        run;
    
        ** sort to get if-else order **;
        proc sort data = pcts_long;
            by _NAME_ percentile;
        run;
    
        ** create your if-then strings using data itself **;
        data str; 
            length STR $100;
            set pcts_long;
            bin = percentile/10;
            by _NAME_;
            if first._NAME_ then do;
                STR = "if "||strip(_NAME_)||" <= "||strip(put(COL1,best.))||" then "||catx("_","recode",_NAME_)||" = "||strip(put(bin,best.))||";";
            end;
            else do;
                STR = "else if "||strip(_NAME_)||" <= "||strip(put(COL1,best.))||" then "||catx("_","recode",_NAME_)||" = "||strip(put(bin,best.))||";";
            end;
        run; 
    
        ** put strings into a list **;
        proc sql noprint;
            select STR
            into: data_step_list separated by " "
            from STR;
        quit;
    
        ** call data step list in final data **;
        data &output.; set &input.;
            &data_step_list.;
        run;
    
        proc print data = &output.(obs=5);
        run;
    
    %MEND;
    
    %stratify(library=work,input=test,output=final);
    

提交回复
热议问题