楼主: Tigflanker
1376 2

[问答] 求助通过look up而决定的变量类型转换 [推广有奖]

  • 8关注
  • 18粉丝

副教授

49%

还不是VIP/贵宾

-

威望
0
论坛币
2321 个
通用积分
9.9128
学术水平
179 点
热心指数
194 点
信用等级
167 点
经验
27443 点
帖子
622
精华
0
在线时间
851 小时
注册时间
2011-3-27
最后登录
2023-5-14

楼主
Tigflanker 发表于 2014-1-17 19:45:27 |AI写论文
100论坛币
请各位帮我个忙,我要做一个put和input转换,但是需要由另一个数据集来决定哪些变量做转换。

首先提供下数据集:

  1. data a;
  2. attrib usubjid length = 8;
  3. attrib RFSTDT length = $8;
  4.   usubjid = 12345;
  5.   x='aaa';
  6.   RFSTDT = '12345';output;
  7. run;

  8. data b;
  9. input NAME $ TYPE;
  10. cards;
  11. RFSTDT 1
  12. USUBJID 2
  13. ;
  14. run;
复制代码

数据集A是需要操作的数据集,数据集B是指示数据集。

A中的变量,例如usubjid是数值型的,RFSTD是字符型的,x是字符型的。
然后数据集B中包含两个值,分别是A的usubjid(注意是小写)和RFSTDT,故按照B中NAME所指示的变量名,做类型转换。
(也就是把usubjid(原本是TYPE = 2,字符型)input成best.;把RFSTDT (原本是TYPE = 1,数值型)put成best.并加个strip)

我要做的话,感觉用array(vname) + hash或者array(vname) + 宏变量,来做;但是貌似最烦的地方都要做新变量再整体rename,因为要考虑普适性,array TYPE_ALLVAR _char_;而不能做全部变量,越想越麻烦。

不知有无直白点的方法,万分感谢,在线等。
  

最佳答案

YLF870214 查看完整内容

这是我以前实习时写的宏,希望对你有帮助: data a; attrib usubjid length = 8; attrib RFSTDT length = $8; usubjid = 12345; x='aaa'; RFSTDT = '12345';output; run; data b; input NAME $ TYPE; cards; RFSTDT 1 USUBJID 2 ; run; %macro ADM_TYPE(in=,out=&in.); proc contents data = &in. out = ADM_TEMP3;run; data ADM_TEMP3(keep = NAME TYPE1);set ADM_TEMP3; NAME = upcase(NAME); TY ...
关键词:Look 类型转换 变量类型 length rename
Bye SAS.
若有缘,能重聚。

沙发
YLF870214 发表于 2014-1-17 19:45:28
这是我以前实习时写的宏,希望对你有帮助:

data a;
attrib usubjid length = 8;
attrib RFSTDT length = $8;
  usubjid = 12345;
  x='aaa';
  RFSTDT = '12345';output;
run;
data b;
input NAME $ TYPE;
cards;
RFSTDT 1
USUBJID 2
;
run;
%macro ADM_TYPE(in=,out=&in.);
proc contents data = &in. out = ADM_TEMP3;run;
data ADM_TEMP3(keep = NAME TYPE1);set ADM_TEMP3;
  NAME = upcase(NAME);
  TYPE1 = TYPE;
run;
%let ADM_TYPE_ALLVAR=;
%let ADM_TYPE_ALLCHAR_TEMP=;
%let ADM_TYPE_ALLNUM_TEMP=;      
proc sort data = ADM_TEMP3;by NAME;run;
proc sort data = b;by NAME;run;
data ADM_TEMP4;
merge ADM_TEMP3 b(keep = NAME TYPE in = yes);
by NAME;
if TYPE ^= TYPE1 and yes then do;
  call symputx('ADM_TYPE_ALLVAR',symget('ADM_TYPE_ALLVAR')||' '||strip(NAME));
end;
run;
data _null_;
  set &in.;
  array ADM_TYPE_ALLCHAR _char_;
  array ADM_TYPE_ALLNUM _numeric_;
  if _N_ = 1 then do;
    do over ADM_TYPE_ALLCHAR;
      call symputx('ADM_TYPE_ALLCHAR_TEMP',symget('ADM_TYPE_ALLCHAR_TEMP')||' '||upcase(vname(ADM_TYPE_ALLCHAR)));
    end;

    do over ADM_TYPE_ALLNUM;
      call symputx('ADM_TYPE_ALLNUM_TEMP',symget('ADM_TYPE_ALLNUM_TEMP')||' '||upcase(vname(ADM_TYPE_ALLNUM)));
    end;
  end;
run;
data &out.;set &in.;
  %do i = 1 %to %eval(%sysfunc(count(&ADM_TYPE_ALLCHAR_TEMP.,%str( ))) + 1);
  %let ADM_TYPE_WHICH = %scan(&ADM_TYPE_ALLCHAR_TEMP.,&i.);
    %if %index("&ADM_TYPE_ALLVAR",&ADM_TYPE_WHICH.) %then %do;
      &ADM_TYPE_WHICH._X = input(&ADM_TYPE_WHICH.,best.);
      drop &ADM_TYPE_WHICH.;
      rename &ADM_TYPE_WHICH._X = &ADM_TYPE_WHICH.;
   %end;
  %end;
  
  %do i = 1 %to %eval(%sysfunc(count(&ADM_TYPE_ALLNUM_TEMP.,%str( ))) + 1);
  %let ADM_TYPE_WHICH = %scan(&ADM_TYPE_ALLNUM_TEMP.,&i.);
    %if %index("&ADM_TYPE_ALLVAR",&ADM_TYPE_WHICH.) %then %do;
      &ADM_TYPE_WHICH._X = strip(put(&ADM_TYPE_WHICH.,best.));
      drop &ADM_TYPE_WHICH.;
      rename &ADM_TYPE_WHICH._X = &ADM_TYPE_WHICH.;
   %end;
  %end;
run;
%mend ADM_TYPE;
%ADM_TYPE(in=a,out=c);


已有 2 人评分论坛币 学术水平 热心指数 信用等级 收起 理由
Imasasor + 200 精彩帖子
Tigflanker + 1 + 1 + 1 谢谢,看来没简便的方法了。。

总评分: 论坛币 + 200  学术水平 + 1  热心指数 + 1  信用等级 + 1   查看全部评分

藤椅
farmman60 发表于 2014-1-19 14:11:47

data a;
input id lastname  $ sex age $;
cards;
1234 AFD 1 23
2365 FDG 2 35
8762 JKK 1 41
;
run;

data b;
input NAME $ TYPE $ ;
cards;
id    C
sex   C
age   N
;
run;

proc sql;
select name into:varlist_C separated by ' ' from b where type='C';
select cats('_',name) into:_varlist_C separated by ' ' from b where type='C';
select name into:varlist_N separated by ' ' from b where type='N';
select cats('_',name) into:_varlist_N separated by ' ' from b where type='N';
quit;

data want;
  if 0 then set b;
  if _n_=1 then do;
  declare hash h(dataset:'b');
  h.definekey('name','type');
  h.definedata(all:'y');
  h.definedone();
  end;
  set a;
  array change_type_c $ &varlist_c;
  array _change_type_c $ &_varlist_c;
  array change_type_n  &varlist_n;
  array _change_type_n  &_varlist_n;
   do over change_type_c;
    _name=vname(change_type_c);
        _type=vtype(change_type_c);
        rc=h.find(key:_name,key:_type);
        if rc^=0 then do;
                  _change_type_c=put(change_type_c,8.);
        end;
        end;
  do over change_type_n;
    _name=vname(change_type_n);
        _type=vtype(change_type_n);
        rc=h.find(key:_name,key:_type);
        if rc^=0 then do;
                  _change_type_n=input(change_type_n,best8.);
        end;
        end;
        keep lastname &_varlist_c  &_varlist_n;
    run;

proc sql;
  select name||'='||compress(name,'_') into: all_name separated by ' ' from dictionary.columns
      where libname='WORK' and memname='WANT' and name contains '_';
  quit;

proc datasets lib=work nolist;
modify want;
rename &all_name;
run;
已有 1 人评分学术水平 热心指数 信用等级 收起 理由
Tigflanker + 1 + 1 + 1 学习了,非常感谢,很简洁!!

总评分: 学术水平 + 1  热心指数 + 1  信用等级 + 1   查看全部评分

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

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