sas 中的第一次和最后一次观察
Posted
技术标签:
【中文标题】sas 中的第一次和最后一次观察【英文标题】:first and last observations in sas 【发布时间】:2016-06-29 18:59:50 【问题描述】:我正在尝试根据基线日期(在我的数据集中称为baseline_doc)为所有相同的client_id分组标记第一个和最后一个观察结果。
例如,我希望我的最终数据集如下所示:
Client_id Baseline_Date First.baseline_doc Last.baseline_doc
--------- ------------------ ------------------ -----------------
1 April 1 2016 0 0
1 April 20 2016 0 1
1 January 1 2016 1 0
2 January 1 2016 1 0
2 January 20 2016 0 1
3 February 20 2016 1 1
请注意如何在第一个和最后一个 client_id 的类似分组中为 client_id 的第一个实例和该 client_id 的最后一个实例标记,然后在每个 client_id 分组中第一个和最后一个观察被标记-第一个日期标记为 1 first.baseline_doc 和最后一个日期(或最近的)被标记为 last.baseline_doc 这是我正在使用的代码:
data FA_CA_DADOS_CLEAN_DELETED;
set fa_ca_dados_clean2;
by client_id baseline_doc;
firstclient_id = first.client_id;
lastclient_id = last.client_id;
firstBaseline_doc = first.baseline_doc;
lastBaseline_doc = last.baseline_doc;
run;
但是,我的代码并没有给我想要的输出。发生的事情是每个 client_id 都被标记为 last.baseline_doc 的 1 但肯定有一些应该是 0 b/c 我有不同日期的重复 client_ids。
我做错了什么?
我直接从这个资源中复制了这段代码: https://onlinecourses.science.psu.edu/stat481/node/9
它有我想要的输出,所以我不确定发生了什么。
在运行上面的代码之前,我按 client_id 和 baseline_doc 进行了排序!
有人可以帮帮我吗?
【问题讨论】:
你肯定不明白。first.something
表示此观察是第一个具有一定something
的观察。如果您将 first.baseline_doc
用于完全不同的概念,您真的会让您的同事感到困惑。
也许您应该首先按 Client_id、Baseline_Date 对输入数据进行排序?
【参考方案1】:
用
读入数据后data myData;
input @01 Client_id 1.
@03 Baseline_Doc date9. ;
format Baseline_Doc yymmdd10.;
datalines;
1 1Apr2016 0 0
1 20Apr2016 0 1
1 1Jan2016 1 0
2 1Jan2016 1 0
2 20Jan2016 0 1
3 20Feb2016 1 1
;
run;
这样就可以了:
proc sql;
select all.*
, case baseline_Doc when baseline_min then 1 else 0 end as baseline_start
, case baseline_Doc when baseline_max then 1 else 0 end as baseline_stop
from myData all inner join
( select Client_id
, min(baseline_doc) as baseline_min
, max(baseline_doc) as baseline_max
from myData
group by Client_id ) as min_max on all.Client_id = min_max.Client_id;
quit;
但是,它可能会带来不愉快的惊喜,因为根据 SQL 的规范,它不必保留顺序。
【讨论】:
【参考方案2】:如果我理解正确,您想在每个 client_id 中标记最早和最晚的日期。为此,您需要查找 first.client_id 和 last.client_id,而不是 first.baseline_doc 和 last.baseline_doc。将 first.x / last.x 视为等效于“这是当前值为 x 的第一行/最后一行”。
试试这个:
data myData;
input @01 Client_id 1.
@03 Baseline_Doc date9. ;
format Baseline_Doc yymmdd10.;
datalines;
1 1Apr2016 0 0
1 20Apr2016 0 1
1 1Jan2016 1 0
2 1Jan2016 1 0
2 20Jan2016 0 1
3 20Feb2016 1 1
;
run;
proc sort data = mydata;
by client_id baseline_doc;
run;
data want;
set mydata;
by client_id;
first_baseline_doc = first.client_id;
last_baseline_doc = last.client_id;
run;
【讨论】:
有了你的答案,你就不会得到想要查看@chiccaboomberry 的结果数据【参考方案3】:如果您想 100% 确定订单被保留,您可以这样做
按基线日期升序对输入进行排序,但要记住原来的观察号;
data myInput;
input @01 Client_id 1.
@03 Baseline_Doc date9. ;
format Baseline_Doc yymmdd10.;
obsNr = _N_;
datalines;
1 1Apr2016 0 0
1 20Apr2016 0 1
1 1Jan2016 1 0
2 1Jan2016 1 0
2 20Jan2016 0 1
3 20Feb2016 1 1
;
run;
proc sort data = myInput out=myTemp;
by client_id baseline_doc;
run;
标记第一个和最后一个基线日期;
data myTemp;
set myTemp;
by client_id baseline_doc;
baseline_start = first.client_id;
baseline_end = last.client_id;
run;
恢复原来的顺序,忘记obsNr;
proc sort data = myTemp out=myResult(drop=obsNr);
by obsNr;
run;
【讨论】:
【参考方案4】:data myData;
input @01 Client_id 1.
@03 Baseline_Doc date9. ;
format Baseline_Doc yymmdd10.;
datalines;
1 1Apr2016 0 0
1 20Apr2016 0 1
1 1Jan2016 1 0
2 1Jan2016 1 0
2 20Jan2016 0 1
3 20Feb2016 1 1
;
run;
proc sort data = mydata;
by client_id baseline_doc;
run;
data want;
set mydata baseline_doc;
by client_id baseline_doc;
if first.client_id then First.baseline_doc = 1;
else First.baseline_doc = 0;
if last.client_id then Last.baseline_doc = 1;
else Last.baseline_doc = 0;
run;
【讨论】:
这不能回答问题(第一个和最后一个变量总是被丢弃),由于使用了 first.baseline_doc,这很令人困惑,除此之外,它几乎与我的答案完全相同.以上是关于sas 中的第一次和最后一次观察的主要内容,如果未能解决你的问题,请参考以下文章