Sas 计数记录了午夜的通行证

Sas 计数记录了午夜的通行证,sas,Sas,我有两个数据集: 1) 让我们将第一个数据集称为“提供者”。它包含一年的供应商列表(超过3900个班次/记录)、他们轮班的日期和班次类型。请注意,存在跨越午夜的换档类型 Date Provider Shift 1/8/2019 Bob ED A/B 11p-7a (ED A/B) 1/10/2019 Bob ED C/D

我有两个数据集:

1) 让我们将第一个数据集称为“提供者”。它包含一年的供应商列表(超过3900个班次/记录)、他们轮班的日期和班次类型。请注意,存在跨越午夜的换档类型

          Date             Provider        Shift
          1/8/2019           Bob           ED A/B 11p-7a (ED A/B)
          1/10/2019          Bob           ED C/D 11p-7a (ED C/D)
          1/16/2019          Bob           ED C 3p-12a (ED C)
          1/9/2019           Sue           UMC 5p-2a (UMC)
          1/11/2019          Bob           ED C/D 11p-7a (ED C/D)
          1/13/2019          Bob           ED PH/night 10p-4a (ED PH/night)
2) 我还有另一个数据集——“患者”。它包含一年的FINs值、他们看医生的日期/时间,以及他们在我们所在地看到的所有患者的医生姓名

            FIN        Date               Provider Name
             1      1/8/2019 23:40           Bob 
             2      1/9/2019 01:46           Timbo
             3      1/9/2019 01:30           Bob
             4      1/9/2019 05:06           Patty
             5      1/9/2019 02:50           Bob
             6      1/9/2019 17:23           Sue
             7      1/9/2019 06:45           Mike
             8      1/10/2019 01:35          Sue
我希望创建一个新的数据集,其中包含给定轮班期间看到的患者数量

例如,数据集如下所示:

             Shift date    Shift                         FIN             Provider 
              1/8/2019     ED A/B 11p-7a (ED A/B)         1                Bob
              1/8/2019     ED A/B 11p-7a (ED A/B)         3                Bob
              1/8/2019     ED A/B 11p-7a (ED A/B)         5                Bob
              1/9/2019     UMC 5p-2a (UMC)                6                Sue
              1/9/2019     UMC 5p-2a (UMC)                8                Sue
通过合并两个数据集,然后根据日期和提供者名称进行匹配,我可以非常轻松地创建此数据集;然而,正如我之前提到的,有些班次跨越了午夜,所以我无法按日期匹配

我对收集数据感兴趣的大概有20种不同的班次类型,其中6种跨越午夜。我需要对我的数据进行结构化,以便说如果一个提供者在2019年1月8日轮班工作ED a/B 11p-7a(ED a/B),那么计算他/她在2019年1月9日上午7点之前看到的任何患者?如果可能的话,我需要创建某种宏(我想)


希望这是有意义的-谢谢你的帮助

您需要处理
提供程序
数据以计算班次开始和结束日期时间。这将需要定位
##p-#a
,并且可能还需要定位
#a-#a
#a-#p
#p-#p
中的文本部分

在计算了shift日期时间后,可以通过以下方式连接数据:

  patients
join 
  provider
on
  patients.date between provider.shift_start and provider.shift_end
& patients.provider = provider.provider
示例

data provider;
attrib
  date informat=mmddyy10. format=mmddyy10.
  provider length=$10
  shift length=$60
;
input date& provider& shift&; datalines;
1/8/2019     Bob     ED A/B 11p-7a (ED A/B)
1/10/2019    Bob     ED C/D 11p-7a (ED C/D)
1/16/2019    Bob     ED C 3p-12a (ED C)
1/9/2019     Sue     UMC 5p-2a (UMC)
1/11/2019    Bob     ED C/D 11p-7a (ED C/D)
1/13/2019    Bob     ED PH/night 10p-4a (ED PH/night)
1/15/2019    Bob     ED PH/night 10p-9p (ED PH/night)
1/17/2019    Bob     ED PH/night 2-11a (ED PH/night)
;

data patients;
attrib
  fin length=8
  service_dt length=8 format=datetime20. informat=anydtdtm20.
  provider length=$10
;
input FIN&  service_dt&  Provider&; datalines;
1   1/8/2019 23:40     Bob 
2   1/9/2019 01:46     Timbo
3   1/9/2019 01:30     Bob
4   1/9/2019 05:06     Patty
5   1/9/2019 02:50     Bob
6   1/9/2019 17:23     Sue
7   1/9/2019 06:45     Mike
8   1/10/2019 01:35    Sue
;

* compute shift start and end datetimes;
* presume the shift time ranges are valid;
* this example does not deal with start and ends at noon or midnight; 
data provider_range;
  set provider;

  rxid = prxparse('/(\d{1,2})(a|p)-(\d{1,2})(a|p)/');

  if prxmatch(rxid,shift) then do;
    length t1 $2 p1 $1 t2 $2 p2 $1;
    t1 = prxposn(rxid,1,shift);  t1n=input(t1,2.);
    p1 = prxposn(rxid,2,shift);
    t2 = prxposn(rxid,3,shift);  t2n=input(t2,2.);
    p2 = prxposn(rxid,4,shift);

    select (p1||p2);
      when ('aa', 'pp') do;
              shift_start = dhms(date, t1n+12*(p2='p'),0,0);
              shift_end   = dhms(date, t2n+12*(p2='p'),0,0);
            end;
      when ('ap') do;
              shift_start = dhms(date, t1n+0,0,0);
              shift_end   = dhms(date, t2n+12,0,0);
            end;
      otherwise /* pa */ do;
              shift_start = dhms(date, t1n+12,0,0);
              shift_end   = dhms(date, t2n+24,0,0);
            end;
    end;
  end;
  else do;
    put 'ERROR: Invalid shift, '  shift ;
    delete;
  end;

  format shift_start shift_end datetime20.;
  drop rxid t1: p1: t2: p2:;
run;

* this join does not use SAS SQL BETWEEN, the join criteria 
* uses explicit construct  a <= b and b <= c instead;

proc sql;
  create table want as
  select 
    provider.date as shift_date,
    provider.shift,
    patients.service_dt,
    patients.fin,
    patients.provider
  from patients
  join provider_range as provider
    on patients.provider = provider.provider and
       provider.shift_start <= patients.service_dt and
       provider.shift_end >= patients.service_dt
  order by
    fin
  ;
quit;
数据提供者;
阿特里布
日期信息=mmddyy10。格式=mmddyy10。
提供者长度=$10
班次长度=$60
;
输入日期、提供者和班次;数据线;
2019年1月8日Bob ED A/B 11p-7a(ED A/B)
2019年10月1日Bob ED C/D 11p-7a(ED C/D)
2019年1月16日Bob ED C 3p-12a(ED C)
2019年1月9日起诉联电5p-2a(联电)
2019年11月1日Bob ED C/D 11p-7a(ED C/D)
2019年1月13日Bob ED PH/夜间10p-4a(ED PH/夜间)
2019年1月15日Bob ED PH/夜间10p-9p(ED PH/夜间)
2019年1月17日鲍勃教育博士/夜间2-11a(教育博士/夜间)
;
患者资料;
阿特里布
翅片长度=8
服务长度=8格式=datetime20。informat=anydtm20。
提供者长度=$10
;
输入FIN&service_dt&Provider&;数据线;
2019年1月8日23:40北京时间
2019年1月9日01时46分Timbo
2019年1月9日01:30北京时间
4 2019年1月9日05:06帕蒂
5 2019年1月9日02:50北京时间
2019年6月1日9时17分
2019年11月9日06:45迈克
2019年11月10日01时35分
;
*计算移位开始和结束日期时间;
*假定换档时间范围有效;
*本例不涉及中午或午夜的开始和结束;
数据提供者范围;
设置提供者;
rxid=prxparse('/(\d{1,2})(a | p)-(d{1,2})(a | p)/');
如果PRX匹配(rxid,shift),则执行;
长度t1$2 p1$1 t2$2 p2$1;
t1=prxposn(rxid,1,移位);t1n=输入(t1,2.);
p1=prxposn(rxid,2,移位);
t2=prxposn(rxid,3,移位);t2n=输入(t2,2.);
p2=prxposn(rxid,4,移位);
选择(p1 | | p2);
当('aa','pp')做时;
班次开始=dhms(日期,t1n+12*(p2='p'),0,0);
班次=dhms(日期,t2n+12*(p2='p'),0,0);
结束;
当(‘ap’)发生时;
班次开始=dhms(日期,t1n+0,0,0);
班次=dhms(日期,t2n+12,0,0);
结束;
否则/*pa*/do;
班次开始=dhms(日期,t1n+12,0,0);
班次=dhms(日期,t2n+24,0,0);
结束;
结束;
结束;
否则你会;
输入“错误:无效移位”,移位;
删除;
结束;
格式化班次\开始班次\结束日期时间20。;
滴入rxid t1:p1:t2:p2:;
跑
*此联接不在联接条件之间使用SAS SQL

*在最终数据中使用显式构造a,为什么FIN=2归于Bob而不是Timbo?鳍应该是1,3,5,6,8吗?@Richard,是的,你是对的,我的错误,我已经纠正了这个错误。谢谢!我正在努力了解您的解决方案,并在下面找到了一个有用的资源,但我想知道您是否可以对一些代码的工作方式进行评论,特别是prxparse、prxposn和when('aa,'pp')。。。