SAS中文论坛

 找回密码
 立即注册

扫一扫,访问微社区

楼主: shiyiming
打印 上一主题 下一主题

SAS程序员测试(二)

[复制链接]

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
21#
 楼主| 发表于 2004-6-7 13:59:52 | 只看该作者

我也贴一个,适应性和效率有待考证!

data tem;
retain ord 0;
set tem;
x=lag(vol);
if vol=x then ord=ord;else ord=ord+1;
run;

proc sort;by id ord date;run;

data first last;
set tem;
by id ord;
if first.ord then output first;
if last.ord then output last;
run;

data final;
merge first (rename=(date=date1))
      last (rename=(date=date2));
by id ord;
run;
proc print;
var id date1 date2 vol;
run;
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
22#
 楼主| 发表于 2004-7-28 02:19:17 | 只看该作者

simplest solution

I think this is the simplest solution:

data res(drop=date);
  set tem;
  by id vol notsorted;
  retain bdate edate;
  format bdate yymmdd10. edate yymmdd10.;
  if first.vol then bdate=date;
  if last.vol then do;
    edate=date;
    output;
  end;
run;
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
23#
 楼主| 发表于 2004-7-28 12:45:43 | 只看该作者

没有用到转置,只用到data step 和proc sort,数据结果在result?

data tem;
input id:$1. date:yymmdd10. vol;
format date yymmdd10.;
cards;
0 20020101 0
1 20020101 10
1 20020102 10
1 20020103 10
1 20020108 9
1 20020109 9
1 20020110 9
2 20020101 9
2 20020102 8
2 20020103 14
2 20020104 8
2 20020108 11
2 20020109 11
2 20020110 12
;run;
data tem_1;
retain s 0;
set tem;
if _n_>1 & (id ^=lag(id) | vol ^=lag(vol)) then s+1;
run;
proc sort data=tem_1;
by s;
run;
data tem_2;
set tem_1;
by s;
if first.s  then output;
if last.s then output;
run;
proc sort data=tem_2;
by s;
run;
data result;
format sdate edate yymmdd10.;
set tem_2;
by s;
sdate=lag(date);
edate=date;
if last.s=1;
run;
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
24#
 楼主| 发表于 2004-8-24 13:05:38 | 只看该作者

re:程序员测试

proc sort data=tem;
by id vol date;
run;
data rst(drop=date);
set tem;
by id vol;
format sdate yymmdd10.;
format edate yymmdd10.;
if first.vol then sdate=date;
if last.vol then do;
  edate=date;
  output;
end;
retain;
run;
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
25#
 楼主| 发表于 2004-9-16 12:51:13 | 只看该作者

My Solution:

data tem;
input id:$1. date:yymmdd10. vol;
format date yymmdd10.;
cards;
0 20020101 0
1 20020101 10
1 20020102 10
1 20020103 10
1 20020108 9
1 20020109 9
1 20020110 9
2 20020101 9
2 20020102 8
2 20020103 14
2 20020104 8
2 20020108 11
2 20020109 11
2 20020110 12
;run;

proc sql;
select distinct id, min(date) as SDate format=yymmdd10., max(date) as EDate format=yymmdd10., Vol as New_Vol from tem group by id, vol;
quit;
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
26#
 楼主| 发表于 2004-12-1 15:24:29 | 只看该作者

sql

data Sasuser.test;
input id:$1. date:yymmdd10. vol;
format date yymmdd10.;
cards;
0 20020101 0
1 20020101 10
1 20020102 10
1 20020103 10
1 20020108 9
1 20020109 9
1 20020110 9
2 20020101 9
2 20020102 8
2 20020103 14
2 20020104 8
2 20020108 11
2 20020109 11
2 20020110 12
;run;
proc sql;
create table sasuser.result as
select id,min(date) as starttime,max(date) as endtime,vol from Sasuser.test group by id,vol;
run;
proc print data=sasuser.result;
format starttime YYMMDD10.;
format endtime YYMMDD10.;
run;
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
27#
 楼主| 发表于 2005-3-20 09:23:27 | 只看该作者

似乎这样好一些

基本同意topgun_li的作法,但从题目字面看,还是应排序

proc sort data=tem;
  by id vol;
run;

data result;
  set tem;
  by id vol;
  if first.vol then sdate=date;
  if last.vol then do;
    edate=date;
    new_vol=vol;
    output;
  end;
  keep id sdate edate new_vol;
  format sdate yymmdd10. edate yymmdd10.;
  retain sdate;
run;
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
28#
 楼主| 发表于 2005-4-14 20:33:03 | 只看该作者

Thanks a lot

nice guy!
cool!
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
29#
 楼主| 发表于 2005-6-18 13:11:30 | 只看该作者

今天再看这个远古的贴子, 突然觉得挺有意思! 好像大家都没考虑一

如果原数据中的日期可以重复, 也就是说同一天有2个VOL值(也许不可能发生,但允许数据录入错误), 很多程序就可能有问题! 我试改了一个数, 测试一下看看! 欢迎讨论!!

input id:$1. date:yymmdd10. vol;
format date yymmdd10.;
cards;
0 20020101 0
1 20020101 10
1 20020102 10
1 20020103 10
1 20020108 9
1 20020109 9
1 20020110 9
2 20020101 9
2 20020102 8
2 20020108 14    /* 将原来的 20020103 改成 20020108 */
2 20020104 8
2 20020108 11
2 20020109 11
2 20020110 12
;
run;
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
30#
 楼主| 发表于 2005-6-18 13:37:54 | 只看该作者

A

好久没有看这个帖子了。

谢谢xsmile!,其实这个问题用SQL就可以了,没有必要用Data步。

这个模拟数据是一个优化库存数据存储的模板,好比如仓库存储中productId,date,hold_volume,因为可能多种产品好多日的存量一直数量不变,
所以改用startDate,endDate的存储方式更加简捷。

不可能出现某日,某个productId的重复数据,否则搞不清楚该日该产品的存量到底是多少?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|手机版|Archiver|SAS中文论坛  

GMT+8, 2026-2-5 21:35 , Processed in 0.145688 second(s), 18 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表