楼主: luckycai
10649 13

求移动平均和移动标准差 [推广有奖]

  • 0关注
  • 0粉丝

本科生

2%

还不是VIP/贵宾

-

威望
0
论坛币
400 个
通用积分
0
学术水平
1 点
热心指数
1 点
信用等级
1 点
经验
513 点
帖子
57
精华
0
在线时间
43 小时
注册时间
2010-3-6
最后登录
2016-1-2

楼主
luckycai 在职认证  发表于 2012-9-14 16:33:04 |AI写论文
50论坛币
想了半天,找了半天,才来求教各位大侠了。
我的数据是这样的
date x
2008Q1 1
2008Q1 1
2008Q2 2
2008Q2 2
2008Q3 3
2008Q4 4
2008Q4 3
2009Q1 2
2009Q2 1
2009Q3 3
2009Q3 2
........
一共有几年,每个季度的变量个数是不一样的。想要每季度得到一个基于前四个季度的x的移动平均和移动标准差,在数据开始阶段,若季度数量不足4个,如2008Q3,就使用2008Q1~2008Q2的数据求平均和标准差。
形如
date     x  ave  std (略)
2008Q1 1  1   (2008Q1的平均)
2008Q1 1
2008Q2 2  1   (2008Q1的平均)
2008Q2 2
2008Q3 3  1.5 (2008Q1~2008Q2的平均)
2008Q4 4  1.8   (2008Q1~2008Q3的平均)
2008Q4 3
2009Q1 2  16/7  (2008Q1~2008Q4的平均)
2009Q2 1   ?(2008Q2~2009Q1的平均)
2009Q3 3 ? (2008Q3 ~2009Q2)
2009Q3 2
谢谢大家,为表诚意,特意多出点金子感谢愿意分享答案的好心人。

最佳答案

ziyenano 查看完整内容

呵呵~多谢关心 这下应该可以了,是你要求的第二种方法 proc iml; use ex1; read all var{year q x} into g; q=j(nrow(g),2,0); do i=1 to nrow(g); if i=1 then do; limit=(g[,1]-g)*4+g[,2]-g; locate=loc(limit>=-3 & limit=-3 & limit
关键词:移动平均 标准差 date 变量个数 各位大侠 移动 标准差

回帖推荐

ziyenano 发表于3楼  查看完整内容

data ex; input date $ x; cards; 2008Q1 1 2008Q1 1 2008Q2 2 2008Q2 2 2008Q3 3 2008Q4 4 2008Q4 3 2009Q1 2 2009Q2 1 2009Q3 3 2009Q3 2 ; run; data ex1; set ex; year=input(scan(date,1,'Q'),4.); q=input(scan(date,2,'Q'),1.); run; proc iml; use ex1; read all var{year q x} into g; q=j(nrow(g),2,0); do i=1 to nrow(g); if i=1 then do; q=g ; end; else if all( ...

本帖被以下文库推荐

沙发
ziyenano 发表于 2012-9-14 16:33:05
luckycai 发表于 2012-9-15 09:52
您好!首先真的非常感激您大半夜的回复,请注意休息喔!

这里第一行的问题是解决了,但是我发现了另一 ...
呵呵~多谢关心
这下应该可以了,是你要求的第二种方法
proc iml;
use ex1;
read all var{year q x} into g;
q=j(nrow(g),2,0);     
do i=1 to nrow(g);  
   if i=1 then do;
   limit=(g[,1]-g[i,1])*4+g[,2]-g[i,2];
   locate=loc(limit>=-3 & limit<=0);
   q[i,1]=g[locate,3][:];              
   q[i,2]=((g[locate,3]-g[locate,3][:])##2)[:]##0.5;
   end;
  else if all(g[i,1:2]=g[i-1,1:2]) then do;   
   q[i,1]=.;                                    
   q[i,2]=.;
   end;
   else do;
   limit=(g[,1]-g[i,1])*4+g[,2]-g[i,2];   /*将年份的差乘以4,加上季度的差,赋值给limit*/
   locate=loc(limit>=-3 & limit<=0);      /*用loc函数找出limit值在[-3,0]之间的观测位置,即要求的四个季度的所有观测的位置*/     
   q[i,1]=g[locate,3][:];              
   q[i,2]=((g[locate,3]-g[locate,3][:])##2)[:]##0.5;
   end;
end;
create ans from q[colname={'mean','std'}];
append from q;
quit;
data ans;
merge ex ans;
run;








藤椅
ziyenano 发表于 2012-9-14 18:23:13

data ex;
input
date $ x;
cards;
2008Q1 1
2008Q1 1
2008Q2 2
2008Q2 2
2008Q3 3
2008Q4 4
2008Q4 3
2009Q1 2
2009Q2 1
2009Q3 3
2009Q3 2
;
run;

data ex1;
set ex;
year=input(scan(date,1,'Q'),4.);
q=input(scan(date,2,'Q'),1.);
run;

proc iml;
use ex1;
read all var{year q x} into g;
q=j(nrow(g),2,0);
do i=1 to nrow(g);
   if i=1 then do;
   q[i,1]=g[i,3] ;
   end;
   else if all(g[i,1:2]=g[i-1,1:2]) then do;
   q[i,1]=.;
   q[i,2]=.;
   end;
else do;
   q[i,1]=g[1:i-1,3][:];
   q[i,2]=((g[1:i-1,3]-g[1:i-1,3][:])##2)[:];
end;
end;
create ans from q[colname={'mean','std'}];
append from q;
quit;
data ans;
merge ex ans;
run;
已有 1 人评分经验 论坛币 收起 理由
bakoll + 3 + 3 精彩帖子

总评分: 经验 + 3  论坛币 + 3   查看全部评分

板凳
luckycai 在职认证  发表于 2012-9-14 19:34:15
ziyenano 发表于 2012-9-14 18:23
data ex;
input
date $ x;
one thousand thanks! 完全正确!不过我没有接触过iml语言,ls能不能好事做到底,稍微注释下,让我们能多懂一点

报纸
luckycai 在职认证  发表于 2012-9-14 20:46:57
ziyenano 发表于 2012-9-14 18:23
data ex;
input
date $ x;
发现一个奇怪的问题,我调用了这一段程序,数据从2008开始的,2008Q1的std算出来居然是0,2008Q1一共一千多个数据啊,另外均值也与单独计算该季度内均值不同

地板
luckycai 在职认证  发表于 2012-9-14 20:59:36
luckycai 发表于 2012-9-14 19:34
one thousand thanks! 完全正确!不过我没有接触过iml语言,ls能不能好事做到底,稍微注释下,让我们能多 ...
改变了一下您给的实例的值,发现问题出现在第一次计算均值和标准差上上。能不能讲解下那段程序是什么意思呀,还有就是改正的方法?
DATE   X   MEAN STD
2008Q1 1   1    0
2008Q1 2   .     .
事实上应该是
DATE   X   MEAN STD
2008Q1 1   1.5    0.5
2008Q1 2   .     .

谢谢您的解答!

7
ziyenano 发表于 2012-9-15 00:40:00
luckycai 发表于 2012-9-14 20:46
发现一个奇怪的问题,我调用了这一段程序,数据从2008开始的,2008Q1的std算出来居然是0,2008Q1一共一千多 ...
一开始理解有歧义,以为2008Q1季度,就是求第一个值的均值和标准差,所以均值永远是第一个值,标准差
没有计算,一直为初值0
改后的程序:

data ex;
input
date $ x;
cards;
2008Q1 1
2008Q1 1
2008Q2 2
2008Q2 2
2008Q3 3
2008Q4 4
2008Q4 3
2009Q1 2
2009Q2 1
2009Q3 3
2009Q3 2
;
run;

data ex1;
set ex;
year=input(scan(date,1,'Q'),4.);
q=input(scan(date,2,'Q'),1.);
run;

proc iml;
use ex1;
read all var{year q x} into g;
q=j(nrow(g),2,0);     
/*给q矩阵赋初值为0,用来存储mean,std*/
do i=1 to nrow(g);   
  /*从矩阵第一行循环到最后一行*/
   if i=1 then do;   
   /*如果是第一行*/
   n=((g[,1]=g[i,1])&(g[,2]=g[i,2]))[+];  
   /*这里计算year=2008且Q=1的记录条数n*/
   q[i,1]=g[1:n,3][:];              
   /*求前n行的均值作为2008Q1的均值*/
   q[i,2]=((g[1:n,3]-g[1:n,3][:])##2)[:]##0.5;
   /*这里其实是求前n行的std,iml中的std函数不是很好用,这里其实是按标准差公式算的,即每个记录减去均值,求平方和的均值,最后开根号*/
   end;
   else if all(g[i,1:2]=g[i-1,1:2]) then do;   
   /*如果不是第一行,且该行year的值等于上一行year的值,Q的值也相等,那该行的均值标准差为空值*/
   q[i,1]=.;                                    
   q[i,2]=.;
   end;
  else do;                                    
  /*如果都不属于上述情况,即每年,每个季度的第一个值,就求它上面所有行的均值以及标准差*/
   q[i,1]=g[1:i-1,3][:];
   q[i,2]=((g[1:i-1,3]-g[1:i-1,3][:])##2)[:]##0.5;   
   /*之前的程序其实求的方差,这边添加##0.5,表示矩阵每个元素开0.5次方,即开根,也可以用sqrt函数,效果一样*/
end;
end;
create ans from q[colname={'mean','std'}]; /*将q矩阵导入到ans数据集中,列名称分别为mean 和 std*/
append from q;
quit;
data ans;
merge ex ans;
run;

8
luckycai 在职认证  发表于 2012-9-15 09:52:48
ziyenano 发表于 2012-9-15 00:40
一开始理解有歧义,以为2008Q1季度,就是求第一个值的均值和标准差,所以均值永远是第一个值,标准差
没 ...
您好!首先真的非常感激您大半夜的回复,请注意休息喔!

这里第一行的问题是解决了,但是我发现了另一个问题,就是您说的“ /*如果都不属于上述情况,即每年,每个季度的第一个值,就求它上面所有行的均值以及标准那*/,就没能体现移动平均的效果了,而是对它之前的所有行进行了计算。我希望得到的是  比如对于 2009q3,mean 和std 是根据 2008Q3——2009Q2或者是2008Q4——2009Q3(两种定义,均只包含4个季度,我提出问题的时候用的是第一种定义,但是现在更希望使用第二种定义方法),而您上面的程序是对2008Q1~2009Q2求的平均和std。又如2012Q2的mean和std,想要的是根据2011Q3-2012Q2来计算的。
不管如何,真心感谢您的帮助!

9
jingju11 发表于 2012-9-15 10:08:48
  1. data simu;
  2.   do year =2008 to 2012;...
  3.     if _2; run;
复制代码
我觉得2008Q1有计算值的话,逻辑和随后的不一致。而且计算值和2008Q2总是相同的。京剧

10
luckycai 在职认证  发表于 2012-9-15 10:13:37
jingju11 发表于 2012-9-15 10:08
我觉得2008Q1有计算值的话,逻辑和随后的不一致。而且计算值和2008Q2总是相同的。京剧
亲,我可以接受稍微改变下移动平均的定义,比如2008q2的mean std是由2008Q1 和2008Q2的数据来计算的,又如2012Q2的mean和std,想要的是根据2011Q3-2012Q2来计算的。
每季度的记录超过1W,而且具体多少条是不定的,所以我觉得不能采用你说的那个办法。

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

本版微信群
加好友,备注cda
拉您进交流群
GMT+8, 2026-1-2 21:46