楼主: z8938560
2326 11

[其他] 有关于一段sas数据筛选问题的代码求助 [推广有奖]

  • 1关注
  • 2粉丝

硕士生

13%

还不是VIP/贵宾

-

威望
0
论坛币
1555 个
通用积分
2.0000
学术水平
0 点
热心指数
0 点
信用等级
0 点
经验
766 点
帖子
75
精华
0
在线时间
142 小时
注册时间
2015-2-9
最后登录
2020-12-11

楼主
z8938560 在职认证  发表于 2017-4-14 17:20:09 |AI写论文
88论坛币
题目是这样的:
      有一个交易表,表名为trans,字段如下:card_no(卡号),date(交易日期),amt(交易金额)按照要求写出满足下列条件的SAS语句:
    查找2012年6、7、8月有交易产生但9、10月没有交易且6、7、8月份交易额在51到100元之间的卡号。(可以将没有交易理解为交易额为0,交易日期形式也都随你怎么想)。


    谢谢各位的帮忙!

最佳答案

foocares 查看完整内容

噢,那按照这个解释,我的理解其实date这个变量就不存在了,因为amt已经含有时间的信息。 按照标准的SQL格式,card_no是primary key,类似于唯一的标识用户ID,每一个ID的行为记录为每一行的关系数据。 而原文中的amt,其实可以按列来扩展,是已按月份区分的交易数额记录。 与之相对的数据结构在SQL关系表或者SAS数据集里大概是这个样子: obs card_no amt1 amt2 amt3 ... amt12 1 xxx 789 ...

回帖推荐

foocares 发表于2楼  查看完整内容

噢,那按照这个解释,我的理解其实date这个变量就不存在了,因为amt已经含有时间的信息。 按照标准的SQL格式,card_no是primary key,类似于唯一的标识用户ID,每一个ID的行为记录为每一行的关系数据。 而原文中的amt,其实可以按列来扩展,是已按月份区分的交易数额记录。 与之相对的数据结构在SQL关系表或者SAS数据集里大概是这个样子: obs card_no amt1 amt2 amt3 ... amt12 1 xxx 789 ...

沙发
foocares 发表于 2017-4-14 17:20:10
噢,那按照这个解释,我的理解其实date这个变量就不存在了,因为amt已经含有时间的信息。
按照标准的SQL格式,card_no是primary key,类似于唯一的标识用户ID,每一个ID的行为记录为每一行的关系数据。
而原文中的amt,其实可以按列来扩展,是已按月份区分的交易数额记录。
与之相对的数据结构在SQL关系表或者SAS数据集里大概是这个样子:

obs     card_no   amt1  amt2  amt3  ...  amt12
1          xxx        789      ...                     . .
2          yyy        123      ...                     . .
3          zzz         456      ...                     . .

这里我将问题先简化,该表中只有2012年12个月的数据(所以amt系列只有十二列),如下图所示:

显然,这个造的数据表里只有两行符合九十两月没有消费的情况,再做进一步筛选六七八月的数据之后我们期望只有一个记录符合筛选,那就是倒数第二行。

对应SAS代码如下:
/*先将原始数据表导入到SAS数据集,假定原表是excel格式*/
PROC IMPORT DATAFILE = 'D:\SAS9\My SAS Files\9.0\Little SAS Book Codes\trans.xls' DBMS=excel OUT = trans REPLACE;
RUN;

data test;
        set trans(obs=10); /*先取前十行小试*/
        array myar(*) amt6 - amt10;  /*数组只关心这五列数据*/
       /*先整理数据,所有交易额缺失的数据均视为0*/
        do i=1 to 5;
                if myar(i) = . then myar(i) = 0;
        end;

        /*先把符合九十月为0的记录给找出来*/
        if not(myar(4)OR myar(5));
        /*然后对六七八月进行筛选*/
        do i = 1 to 3;
                if (51 <= myar(i) <=100);
        end;        
        drop i;
        put card_no=;
run;
导入后的数据集trans, 及筛选运行后的结果显示如下:
card_no=5566778899001122





注意,代码里我的筛选条件是三个月中每个月的消费额都要满足在51到100之间,如果你的本意是三个月的消费总额
要在51到100之间,可对应把条件改为求和便是。

说明下用数组实现的好处:
1. 方便把缺失数据置零
2. 方便用循环下标做筛选操作

最后我想说,其实数据的前期整理往往比SAS本身的程序实现更繁琐也更重要。比如这个例子里,我已经假定了交易额记录是按月记录排序的,这是个很重要的简化假设,如果原始数据里是用更复杂的时间记录,而不是简单的月份标记,那么需要先行调用时间函数来算出哪一列对应是2012年哪个月,那无疑才是更繁重的任务。
附件: 你需要登录才可以下载或查看附件。没有帐号?我要注册
已有 1 人评分论坛币 收起 理由
giresse + 30 精彩帖子

总评分: 论坛币 + 30   查看全部评分

藤椅
piggodmoon 发表于 2017-4-16 02:52:07
附件: 你需要登录才可以下载或查看附件。没有帐号?我要注册

板凳
z8938560 在职认证  发表于 2017-4-17 08:33:33
piggodmoon 发表于 2017-4-16 02:52
你这我都看不到任何内容,还是算了吧

报纸
z8938560 在职认证  发表于 2017-4-17 08:34:02
有没有大神帮小弟看一看的,谢谢啦

地板
z8938560 在职认证  发表于 2017-4-17 14:44:40

7
z8938560 在职认证  发表于 2017-4-18 08:40:06
[em19][em19]有人帮忙不

8
foocares 发表于 2017-4-19 12:09:10
这题如果没有办法记住每个月的交易金额,怎么破?
如果表里只有一个变量amt用来存交易总额,那怎么来甄别是哪个月发生的交易呢?
除非你的交易数据是按月分列的,比如amt1是2012年1月,amt2是2月,依次类推。
那就可以用数组来实现,因为我们严格知道数组下标一一对应的时间各是几月份的数据。
只要找出对应题目时间的这五个下标,再把这五个数组元素按题目条件判定一次,
符合条件的输出卡号,结束当前data步读下一行。

9
z8938560 在职认证  发表于 2017-4-20 16:49:25
foocares 发表于 2017-4-19 12:09
这题如果没有办法记住每个月的交易金额,怎么破?
如果表里只有一个变量amt用来存交易总额,那怎么来甄别是 ...
您好,我补充一下,每个卡号有12条记录,分别是1到12月份,有交易的月份显示具体的交易额,没有交易的显示为0。请问您知道这段代码该怎么写吗,谢谢

10
z8938560 在职认证  发表于 2017-4-24 10:00:50
foocares 发表于 2017-4-21 02:18
噢,那按照这个解释,我的理解其实date这个变量就不存在了,因为amt已经含有时间的信息。
按照标准的SQL格 ...
您好,感谢您的帮助,我基本上看懂了,有一段代码我不是很明白,就是筛选九月十月为0的那段,   if not(myar(4)OR myar(5));这样就是筛选出来的记录为0的嘛?我对if not的用法不是很清楚,谢谢~

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

本版微信群
扫码
拉您进交流群
GMT+8, 2026-2-20 21:23