楼主: expecto14
6436 8

如何用SAS宏计算这个公式? [推广有奖]

  • 3关注
  • 2粉丝

已卖:16份资源

博士生

27%

还不是VIP/贵宾

-

威望
0
论坛币
5828 个
通用积分
15.1117
学术水平
22 点
热心指数
18 点
信用等级
13 点
经验
22183 点
帖子
92
精华
0
在线时间
447 小时
注册时间
2009-7-23
最后登录
2022-11-1

楼主
expecto14 发表于 2011-6-9 14:45:24 |AI写论文
20论坛币
数据集是一个Panel,结构如下:
country   year    vd     qw   qwe    fc     ......      sxb (50个变量)
china     2004     5     322   33      86    ......      322
china     2005     4     22     83      16    ......      75
china     2006     6     352   39      76    ......      32
.
.
.
china     2011     5     652   53      66    ......      82
us
us
us
us.
.
.
.
.
new_zealand
.
.
.
(100个国家)(2004-2011,共8年)     总计100*8=800个观测值

我要做的是:每年,对所有国家的每一个变量按公式换算成0-10的指数(连续的scale)。请大侠帮忙在SAS中实现。。。
比如说,对于2004年,v1变量有100个国家,即100个不同的观测值。将这些值通过公式计算成0-10的指数;同样,2004年v2也有指数。同理,2005-2011年。
这样变换之后仍然是一个panel,公式为:10*(max-obs)/(max-min)

请大侠将SAS代码贴在下面。。。

最佳答案

关键词:SAS宏 如何用 Zealand Country China SAS 公式

沙发
guoluo 发表于 2011-6-9 14:45:25
  1. **create a test dataset;
  2. data test;
  3.   do country = 'c1','c2','c3';
  4.    do i = 1 to 100;
  5.      x = 2 * rannor(123) + 1;
  6.          y = 3 * rannor(123) + 2;
  7.      output;
  8.    end;
  9.   end;
  10.   drop i;
  11. run;

  12. **create a macro variable for each variable;
  13. proc sql;
  14.   create table col as
  15.   select name from dictionary.columns
  16.   where libname='WORK' and memname='TEST' and name not in ('country');
  17. quit;

  18. data _null_;
  19.   set col end=final;
  20.   count+1;
  21.   var = cats('v',count);
  22.   call symputx(var,name);
  23.   if final then call symputx('var_num',_n_);
  24. run;

  25. %macro rescale;
  26. proc means data=test noprint nway;
  27. class country;
  28. var %do i = 1 %to &var_num;
  29.       &&v&i
  30.     %end;;
  31. output out=out max= min=/autoname;
  32. run;

  33. proc sort data=test;
  34. by country;
  35. proc sort data=out;
  36. by country;
  37. run;

  38. data new;
  39.   merge test out;
  40.   by country;
  41.   %do i = 1 %to &var_num;
  42.     n&&v&i = 10 * (&&v&i.._max - &&v&i)/(&&v&i.._max - &&v&i.._min);
  43.   %end;
  44.   keep country %do i = 1 %to &var_num;
  45.                  n&&v&i
  46.                %end;;
  47. run;
  48. %mend;

  49. %rescale
复制代码
已有 1 人评分经验 收起 理由
crackman + 60 鼓励积极发帖讨论

总评分: 经验 + 60   查看全部评分

藤椅
expecto14 发表于 2011-6-9 18:12:38
诸位大侠,揭榜啊~~~~~

板凳
zane_gao 发表于 2011-6-10 00:33:27
一定要用宏?我觉得转个置就行了啊
下面是程序
data test;
infile 'E:\abc.txt';
input country $ year vd qw qwe fc ...... sxb
run;
proc sort data=test out=test1;
by year;
run;
proc transpose data=test1 out=test2;
by year;
id country;
run;
data test3;
set test2;
array raw(100) china us ...... new_zealand......;
maxz=max(china,us......new_zealand.......);
minz=min(china,us......new_zealand......);
do i=1 to 100
  raw(i)=10*(maxz-raw(i))/(maxz-minz);
end;
run;
proc Transpose data=test3 out=test4;
by         year;
id         _name_;
run;

报纸
zane_gao 发表于 2011-6-10 00:37:44
啊,上面的程序少个冒号。另外国家里面应该有字符长于8个的的吧,所以还得加个length声明,我不知道你的国家最长是多少,暂时定个50吧,不够你自己改
data test;
infile 'E:\abc.txt';
length country $ 50;
input country $ year vd qw qwe fc ...... sxb;
run;
proc sort data=test out=test1;
by year;
run;
proc transpose data=test1 out=test2;
by year;
id country;
run;
data test3;
set test2;
array raw(100) china us ...... new_zealand......;
maxz=max(china,us......new_zealand.......);
minz=min(china,us......new_zealand......);
do i=1 to 100
  raw(i)=10*(maxz-raw(i))/(maxz-minz);
end;
run;
proc Transpose data=test3 out=test4;
by         year;
id         _name_;
run;

地板
expecto14 发表于 2011-6-10 14:01:26
非常感谢二位!数据集太大的时候转置可能会比较麻烦,因此还是用宏比较稳妥。

7
expecto14 发表于 2011-6-10 14:09:03
3# guoluo

万分感谢!!!!

不过从我运行的结果来看,这个宏中计算0-10指数的时候,似乎是以每个国家来做的,即,v1变量的观测值在同一国家(c1国家)中转为0-10;我需要的是能将v1变量在同一年(如2004年)将所有国家的观测值变为0-10的指数。麻烦大侠改一下吧。另外,请设置一个txt文件,标价20论坛币,我来购买。。

8
guoluo 发表于 2011-6-10 23:42:59
改了一下
  1. **create a test dataset;

  2. data test;
  3.   do country = 'c1','c2','c3','c4','c5';
  4.    do year = 2004 to 2011;
  5.      x = 2 * rannor(123) + 1;
  6.      y = 3 * rannor(123) + 2;
  7.      output;
  8.    end;
  9.   end;
  10. run;

  11. **create a macro variable for each variable;

  12. proc sql;
  13.   create table col as
  14.   select name from dictionary.columns
  15.   where libname='WORK' and memname='TEST' and name not in ('country','year');
  16. quit;

  17. data _null_;
  18.   set col end=final;
  19.   count+1;
  20.   var = cats('v',count);
  21.   call symputx(var,name);
  22.   if final then call symputx('var_num',_n_);
  23. run;

  24. %macro rescale;
  25. proc means data=test noprint nway;
  26. class year;
  27. var %do i = 1 %to &var_num;
  28.       &&v&i
  29.     %end;;
  30. output out=out max= min=/autoname;
  31. run;

  32. proc sort data=test;
  33. by year country;
  34. proc sort data=out;
  35. by year;
  36. run;

  37. data new;
  38.   merge test out;
  39.   by year;
  40.   %do i = 1 %to &var_num;
  41.     n&&v&i = 10 * (&&v&i.._max - &&v&i)/(&&v&i.._max - &&v&i.._min);
  42.   %end;
  43.   keep country year %do i = 1 %to &var_num;
  44.                       n&&v&i
  45.                     %end;;
  46. run;
  47. %mend;

  48. %rescale
复制代码
也可以用stdize过程
  1. %macro rescale2;

  2. proc stdize data=test out=new2 method=range mult=10;
  3. by year;
  4. var %do i = 1 %to &var_num;
  5.       &&v&i
  6.     %end;;
  7. run;

  8. data new2;
  9.   set new2;
  10.   array newvar(*) %do i = 1 %to &var_num;
  11.                  &&v&i
  12.                %end;;
  13.   do i = 1 to dim(newvar);
  14.     newvar(i) = 10 - newvar(i);
  15.   end;
  16. run;
  17. %mend;

  18. %rescale2
复制代码
论坛币就不用了

9
expecto14 发表于 2011-6-13 12:22:52
8# guoluo
太感谢了!!!!!!!!!!!

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

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