楼主: luorongjin
3938 9

do 循环语句求移动平均代码疑惑 [推广有奖]

  • 1关注
  • 6粉丝

已卖:651份资源

副教授

6%

还不是VIP/贵宾

-

威望
0
论坛币
7111 个
通用积分
12.2590
学术水平
7 点
热心指数
19 点
信用等级
5 点
经验
912 点
帖子
301
精华
0
在线时间
941 小时
注册时间
2010-4-25
最后登录
2024-12-27

楼主
luorongjin 发表于 2012-2-21 11:05:45 |AI写论文
1论坛币
libname ch7 'f:\data_model\book_data\chapt7';
proc sort data=ch7.smooth;by cid month;run;
data smooth;
set ch7.smooth;
by cid;
array lags(12);
lags(1)=lag(balance);
do i=2 to 12;
    lags(i)=lag(lags(i-1));
    end;
do j=12 to 2 by -1;
if j gt cns then lags(j)=.;
  put j=;
end;
if first.cid then do
       cns=0;
       do i=1 to 12;lags(i)=.;
       end;
    end;
cns+1;
mean6=mean(of lags1-lags6);
mean12=mean(of lags1 - lags12);
/*drop i j;*/
run;

这段代码求移动平均,我没完全看懂,哪位大侠能解释下在PDV中怎样运行的?

if语句为什么不能放到前面,第二个do语句是怎么运行的?谢谢各位?




关键词:循环语句 移动平均 libname balance smooth 移动 balance sas do循环

沙发
可~乐 发表于 2012-2-21 13:36:06
呵呵,提供另一个实现方法,不知道会不会好理解点。。。
  1. data a;
  2. input id close@@;
  3. cards;
  4. 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 1 11 1 12 1 13 1 14 1 15
  5. 2 2 2 4 2 6 2 8 2 10 2 12 2 14 2 16 2 18 2 20 2 22 2 24 2 26 2 28 2 30
  6. ;
  7. run;

  8. proc sort data=a;
  9.        by id;
  10. run;

  11. %macro move_average(n,m);
  12. data a;
  13.         do until(last.id);
  14.         set a;
  15.         by id;
  16.         retain sum;
  17.                 sum=0;
  18.                 %do i=0 %to &n;
  19.                         if lag&i(id)^= id then sum=.;
  20.                         sum=sum+lag&i(close);
  21.                 %end;
  22.                 move_average=sum/&m;
  23.                 output;
  24.         end;
  25. run;
  26. %mend;
  27. %move_average(4,5);
复制代码

藤椅
sunset1986 发表于 2012-2-21 16:40:18
学习了
An honest tale speeds best being plainly told.
Cheers!

板凳
jingju11 发表于 2012-2-22 05:08:27
这个程序有点问题。每个cid的最后一个观测无法进入移动平均数的计算。也就是说,MEANS6给出的是该观测之前六个数的均值(如果之前具备6个观测的话)。京剧

报纸
denver 发表于 2012-2-22 05:49:38
求移动平均最好的办法应该是用proc expand的mvave函数吧,可以试一下
Denver大家一起读Paper系列索引贴:
https://bbs.pinggu.org/thread-1430892-1-1.html

地板
luorongjin 发表于 2012-2-24 23:20:48
可~乐 发表于 2012-2-21 13:36
呵呵,提供另一个实现方法,不知道会不会好理解点。。。
你好!首先感谢你的这段代码!原代码用的数据见附件: smooth.txt (2.58 KB)
你可以试试!

7
sunset1986 发表于 2012-2-29 22:48:32
楼主能否把原始数据给我看看,否则我不知道数据中有什么变量~
An honest tale speeds best being plainly told.
Cheers!

8
sunset1986 发表于 2012-3-1 09:55:43
%let p=12;
data e (drop=i j);
        set a;
        if balance ne '.';
        n+1;
        by cid;
/*        (n指代每组的序号)*/
        if first.cid then n=1;
        array a[&p.] b1-b&p.;
        a[1]=lag(balance);
        do i=2 to &p.;
                a[i]=lag(a[i-1]);
        end;
       
        j=&p.;
        do until (j=0);
        if(n<=j) then a(j)=.;
        j=j-1;
        end;

        mean6=mean(of b1-b6);
        mean12=mean(of b1-b12);
run;

您可以尝试上面这段代码
An honest tale speeds best being plainly told.
Cheers!

9
sunset1986 发表于 2012-3-1 21:36:02
do j=12 to 2 by -1;
if j gt cns then lags(j)=.;
  put j=;
end;

我猜楼主是在说这段代码?
这段代码很精彩,比如说刚开始,j=12,在这个时候,1<12,则lags[12]第一行数据=.;同理2、3、4、5、6、7、8、9、10、11都小于12,因此lags[12]的前11个数据都为.;
但是我认为,楼主要求moving average by 12,因此这里if j gt cns应改写为if j ge cns,这样就可以实现lags[12]前12个数据都为.了,您觉得呢?
然后当j=11时,lags[11]的前10个数据都为.;
一次类推,希望能够帮到您
An honest tale speeds best being plainly told.
Cheers!

10
sunset1986 发表于 2012-3-1 21:39:13
现在我们来看楼主的第一个问题:
if j gt cns then lags(j)=.;
  put j=;
end;
这个if是不可以放在do i=12 to 2 by -1前面的,否则j gt cn无从谈起;
if first.cid then do
       cns=0;
       do i=1 to 12;lags(i)=.;
       end;
    end;
cns+1;

这个if的位置是为了找到每一组的第一条数据,然后为每组数据进行赋值;但是如果放在后面也不是不可以,我想如果放在后面的话程序跑不出cns的数值,那加一个retain应该可解决问题。


希望可以帮到您
An honest tale speeds best being plainly told.
Cheers!

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

本版微信群
加好友,备注cda
拉您进交流群
GMT+8, 2025-12-9 11:47