SAS vlookup-查看不仅加入的所有数据

时间:2019-04-08 09:47:37

标签: sas vlookup sas-macro

我想查看“一个”数据集中的所有数据。如果表之间的连接不存在,则覆盖值0。当前代码仅在存在连接的情况下为我提供值。我需要这张桌子:

enter image description here

    data one;
  input lastname: $15. typeofcar: $15. mileage;
datalines;
Jones Toyota 3000
Smith Toyota 13001
Jones2 Ford 3433
Smith2 Toyota 15032
Shepherd Nissan 4300
Shepherd2 Honda 5582
Williams Ford 10532
;

data two;
  input startrange endrange typeofservice & $35.;
datalines;
3000 5000 oil change
5001 6000 overdue oil change
6001 8000 oil change and tire rotation
8001 9000 overdue oil change
9001 11000 oil change
11001 12000 overdue oil change
12001 14000 oil change and tire rotation
15032 14999 overdue oil change
13001 15999 15000 mile check
;


data combine;
do until (mileage<15000);
  set one;
  do i=1 to nobs;
     set two point=i nobs=nobs;
     if startrange = mileage then
        output;
  end;
  end;

run;


proc print;
run;

SAS支持站点上的代码说明: 从DO循环之外的SAS数据集中读取第一个观察值。将FOUND变量分配为0。启动DO循环,从DO循环内的SAS数据集中读取观察值。处理中频条件;如果IF条件为true,则输出观察值并将FOUND变量设置为1。将FOUND变量分配为1将由于DO循环上编码的UNTIL(FOUND)而导致DO循环停止处理。返回DATA步骤的顶部,从DO循环外部的数据集中读取下一个观察值,然后再次执行DATA步骤,直到从DO循环外部的数据集中读取所有观察值。

3 个答案:

答案 0 :(得分:0)

您可以在proc sql中使用LEFT JOIN来实现

one获取所有变量 然后创建两个条件,以在startrangeendrange丢失时填充0

proc sql noprint;
    create table want as
    select t1.*
        , case when t2.startrange=. then 0 else t2.startrange end as startrange
        , case when t2.endrange=. then 0 else t2.endrange end as endrange
        , t2.typeofservice
    from one t1 left join two t2
    on (t1.mileage = t2.startrange)
    ;run;quit;

或者分两步进行(我个人发现数据步的if比proc sql的case when干净。)

proc sql noprint;
    create table want as select *
    from one t1 left join two t2 on (t1.mileage = t2.startrange)
;run;quit;
data want; set want;
    if startrange=. then do; startrange=0; endrange=0; end;
run;

答案 1 :(得分:0)

Data step is not the best way to code this. It is much easier to code fuzzy matches using SQL code.

Not sure why you need to have zeros instead of missing values, but coalesce() should make it easy to provide them.

proc sql ;
  create table combine as
    select a.*
         , coalesce(b.startrange,0) as startrange
         , coalesce(b.endrange,0) as endrange
         , b.typeofservice
    from one a left join two b
    on a.mileage between b.startrange and b.endrange
  ;
quit;

答案 2 :(得分:0)

I can't use proc sql because I need Vlookup inside loop UNTIL. I need another solution.