proc sql vs data step for looking up values form a reference table that includes exceptions

前端 未结 3 1942
-上瘾入骨i
-上瘾入骨i 2021-01-25 18:39

I am trying to find out tax values for a particular good in a particular city in a particular state. Tax values are in a reference table like this:

state    city         


        
3条回答
  •  自闭症患者
    2021-01-25 19:23

    This is a bit long. I use a hash object in these situations. Iteratively "if/then/else" your way through the look up tree attempting to find a value.

    I assume Honolulu chicken should be in "Hawaii all chicken" and not "all all chicken."

    I included a macro I use for creating the hash object. This uses your data, a set up things to look up and creates and output table with the looked up taxes.

    data taxes;
    informat state $8.   
             city $12.     
             Good $12.    
             tax best.;
    input state $ city $ good $ tax;
    datalines;
    all      all      all      0.07
    all      all      chicken  0.04
    all      jackson  all      0.01
    arizona  all      meat     0.02
    arizona  phoenix  meat     0.04
    arizona  tucson   meat     0.03
    hawaii   all      all      0.08
    hawaii   all      chicken  0.11
    nevada   reno     cigar    0.11
    nevada   vegas    cigar    0.13
    ;;;
    run;
    
    data to_look_up;
    informat lu_state $8.   
             lu_city $12.     
             lu_Good $12.  ;
    input lu_state $ lu_city $ lu_good $;
    datalines;
    nevada reno cigar
    nevada reno chicken
    hawaii honalulu chicken
    texas  dallas steak
    ;;;
    run;
    
    %macro create_hash(name,key,data_vars,dataset);
    declare hash &name(dataset:&dataset);
    %local i n d;
    %let n=%sysfunc(countw(&key));
    rc = &name..definekey(
        %do i=1 %to %eval(&n-1);
        "%scan(&key,&i)",
        %end;
        "%scan(&key,&i)"
    );
    %let n=%sysfunc(countw(&data_vars));
    %do i=1 %to &n;
        %let d=%scan(&data_vars,&i);
        rc = &name..definedata("&d");
    %end;
    rc = &name..definedone();
    %mend;
    
    data lookup;
    set to_look_up;
        format tax best.
             state $8.   
             city $12.     
             Good $12. ;
    
        if _N_ = 1 then do;
            %create_hash(scg,state city good, tax,"taxes");
        end;
    
        state = lu_state;
        city =  lu_city;
        good = lu_good;
        tax = .;
    
        rc = scg.find();
        if missing(tax) then do;
            /*No exact match - check if state/good combo exists*/   
            city = "all";
            rc = scg.find();
            if missing(tax) then do;
                /*No state/good combo -- check state only taxes*/
                good = "all";
                rc = scg.find();
                if missing(tax) then do;
                    /*Check good only*/
                    good = lu_good;
                    state = "all";
                    rc = scg.find();
                    if missing(tax) then do;
                        /*Default taxes*/
                        good = "all";
                        rc = scg.find();
                    end;
                end;
            end;
        end;
    run;
    

提交回复
热议问题