Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Date 寻找一种更有效的方法,根据SAS中的日期和分组变量重新构造数据_Date_Sas_Retain - Fatal编程技术网

Date 寻找一种更有效的方法,根据SAS中的日期和分组变量重新构造数据

Date 寻找一种更有效的方法,根据SAS中的日期和分组变量重新构造数据,date,sas,retain,Date,Sas,Retain,原始数据: subject medgrp stdt endt 1 A 7/1/2014 7/31/2014 1 A 7/29/2014 8/30/2014 1 B 7/1/2014 8/15/2014 1 C 8/1/2014 9/1/2014 2 A 4/15/2014 5/15/2014 2 A 5/10/2

原始数据:

subject medgrp  stdt        endt
1       A       7/1/2014    7/31/2014
1       A       7/29/2014   8/30/2014
1       B       7/1/2014    8/15/2014
1       C       8/1/2014    9/1/2014
2       A       4/15/2014   5/15/2014
2       A       5/10/2014   6/10/2014
2       A       6/5/2014    6/15/2014
2       A       7/1/2014    8/1/2014
3       A       6/5/2014    6/15/2014
3       A       6/16/2014   8/1/2014
重组数据:

subject med_pattern stdt_new    endt_new
1       A*B         7/1/2014    7/31/2014
1       A*B*C       8/1/2014    8/15/2014
1       A*C         8/16/2014   8/30/2014
1       C           8/31/2014   9/1/2014
2       A           4/15/2014   6/15/2014
2       A           7/1/2014    8/1/2014
3       A           6/5/2014    8/1/2014
我能够通过将所有记录的
stdt
输出到
endt
将原始数据转换为重新结构化的数据,然后为每个
subject/medgrp
保留一个日期,改革日期周期并创建变量
med_模式

然而,这种方法需要很长时间才能运行,尤其是对于大数据(>3m条记录)


如果您有任何建议可以提高效率,我们将不胜感激

通过
subject
您可以使用日期键控的多数据散列来跟踪
stdt
endt
定义的日期范围内每个日期的
medgrp
活动。哈希的迭代将允许您计算medgrps交叉值

数据已经存在;输入
受试者medgrp$stdt:mmddyy8。完:mmddyy8 ;。;格式stdt endt mmddyy10。;
数据线;
1A 2014年1月7日2014年7月31日
1A 2014年7月29日2014年8月30日
1B 2014年1月7日2014年8月15日
1A 2014年7月15日2014年7月15日
1 C 2014年1月8日2014年1月9日
2A 2014年4月15日2014年5月15日
2A 2014年10月5日2014年10月6日
2 A 2014年6月5日2014年6月15日
2A 2014年1月7日2014年1月8日
3 A 2014年6月5日2014年6月15日
3 A 2014年6月16日2014年8月1日
;
数据交叉点按日期/视图=交叉点按日期;
如果为0,则设置为have;*准备PDV;
如果,那就做;;
声明哈希dg(多数据:'yes',顺序:'a');%*主题日期的第一个哈希;
defineKey总经理(“日期”);
dg.defineData(“日期”、“medgrp”);
dg.defineDone();
电话丢失(日期);格式日期adate cdate mmddyy10。;
声明散列交叉(有序:'a');%*用于重复删除MEDGRP列表的第二个哈希;
crossing.defineKey(“medgrp”);
交叉。定义数据(“medgrp”);
crossing.defineDone();
宣布hiter dgi(“dg”);
宣布希特勒十一世(“穿越”);
结束;
dg.clear();
直到(最后一个主题)为止逐个处理主题;
集有;
按科目划分;
do日期=从stdt到endt;*在日期范围内使用medgrp加载多数据哈希;
dg.add();
结束;
结束;
*检查受试者活动的每个日期;
adate=。;
cdate=-1e9;
当(dgi.next()=0)时,do _i_=1乘以1;
如果日期相等
然后继续;*hiter over multi data将返回每个节点;
else adate=日期;*跟踪活动日期;
*加载哈希以消除medgrp在日期上的重复跟踪;
交叉。清除();
doi=1乘1,而(dg.dou over()=0);
交叉。替换();
结束;
*计算日期上的交叉表示,A*B*。。。通过遍历第二个散列;
席();长度交叉20美元;
交叉=medgrp;
do while(0=席.nEXT());
交叉=catx(“*”,交叉,medgrp);
结束;
如果日期-cdate>1,则集群+1;%*基于数据连续性的航迹聚类;
cdate=日期;

输出;*如果您可以发布用于转换原始数据的代码,这将非常有帮助。请将您的问题更新为文本而不是图像形式的示例数据。您是否有SAS/CONNECT?您已经有了一些产生正确输出的逻辑,因此,如果您将数据拆分为n个部分并并行处理它们,您可以在不需要太多额外工作的情况下将其速度提高n倍。感谢您向我介绍这种方法。我从未遇到过多数据散列。它确实有效,但我唯一关心的是,它比我最初的方法需要更多的时间来运行。我使用10k数据集对其进行了测试。我的方法运行了6.61秒,而这一次运行了21秒。我很惊讶它需要这么长的时间,但没有任何数据进行故障排除。也许有些日期范围很大?10K数据集中有多少主题?受试者将展示哪些日期范围?你能显示你10公里跑步的记录吗?它会告诉你视图发送了多少行?一个可能的怀疑是哈希重置
dg.CLEAR()
crossing.CLEAR()
非常耗时。有一些基于直接索引数组的版本,如果您允许对最大总日期范围、组数和交叉主题体验设置先决条件,则速度可能会快得多如果您想提供10K样本数据,可以链接到google doc或pastebin.com条目
data have; input 
subject medgrp $ stdt: mmddyy8. endt: mmddyy8.; format stdt endt mmddyy10.;
datalines;
1       A       7/1/2014    7/31/2014
1       A       7/29/2014   8/30/2014
1       B       7/1/2014    8/15/2014
1       A       7/15/2014   7/15/2014
1       C       8/1/2014    9/1/2014
2       A       4/15/2014   5/15/2014
2       A       5/10/2014   6/10/2014
2       A       6/5/2014    6/15/2014
2       A       7/1/2014    8/1/2014
3       A       6/5/2014    6/15/2014
3       A       6/16/2014   8/1/2014
;

data crossings_by_date / view=crossings_by_date;
  if 0 then set have; * prep PDV;

  if _n_ then do;    
    declare hash dg(multidata:'yes', ordered:'a');         %* 1st hash for subject dates;
    dg.defineKey('date');
    dg.defineData('date', 'medgrp');
    dg.defineDone();
    call missing (date); format date adate cdate mmddyy10.;

    declare hash crossing(ordered:'a');                    %* 2nd hash for deduping a list of medgrps ;
    crossing.defineKey('medgrp');
    crossing.defineData('medgrp');
    crossing.defineDone();

    declare hiter dgi('dg');
    declare hiter xi('crossing');
  end;

  dg.clear();

  do _n_ = 1 by 1 until (last.subject);  * process subjects one by one;
    set have;
    by subject;
    do date = stdt to endt; * load multidata hash with medgrp over date range;
      dg.add();
    end;
  end;

  * examine each date in which subject had activity; 
  adate = .;
  cdate = -1e9;
  do _i_ = 1 by 1 while (dgi.next() = 0);
    if date eq adate 
      then continue;          * hiter over multi-data will return each node;
      else adate = date;      * track activity date;

    * load hash to dedupe tracking of medgrp on date;
    crossing.clear();
    do _i_ = 1 by 1 while (dg.do_over() = 0);
      crossing.replace();
    end;

    * compute crossing representation on date, A*B*... by traversing 2nd hash;
    xi.first();      length cross $20;
    cross = medgrp;
    do while(0 = xi.next());
      cross = catx('*',cross,medgrp);
    end;

    if date - cdate > 1 then cluster + 1;    %* track cluster based on date continuities;
    cdate = date;

    output;  * <------------ view OUTPUT;
  end;

  keep subject date cross cluster;
run;

* 2nd data step processes view (1st data step);
* determine when date continuity ends or medgrp changes;

data want;
  length subject 8 medgrps $20;
  format stdt endt mmddyy10.;

  do _n_ = 1 by 1 until (last.medgrps);
    set crossings_by_date (rename=cross=medgrps);
    by cluster medgrps notsorted;

    if stdt = . then 
      stdt = date;
  end;

  endt = date;

  keep subject medgrps stdt endt; 
run;