我有一个包含几个数字和字符列的数据集。大多数字符列都是简单的“是”或“否”问题,但有些不是。对于数字列,我觉得我有一个有效的解决方案。对于字符列,我尝试将其最小化,但没有成功。 我想做的,并尝试了一个循环,该循环指出 j = var4的列号时,请使用Big / Small / IU替换。这样做的想法是,由于我可以在%let语句中更改var4的变量,并且代码长度较短,因此这将使代码减少“变量依赖性”。
由于dim语句为我提供了数字或字符列的总数,所以我想有些陈述使我可以将特定变量的列放置在secound循环中。但是,我没有找到这样的声明。
到目前为止,我的代码
%let v1 = var1;
%let v2 = var2;
%let v3 = var3;
%let v4 = var4;
data have;
infile datalines delimiter = '|';
input surveyYear id var1 var2$ var3 var4$20. ;
datalines;
2016 | 1 | 10 | Yes | 5 | BIG
2016 | 2 | 6 | YES | 8 | Big
2016 | 3 | 8 | YEs | 99999 | big
2016 | 4 | . | yes | 5 | 99999
2017 | 5 | 6 | No | 7 | SMALL
2017 | 6 | 5 | Ye | . | small
2017 | 7 | 99999 | no | 3 | 99999
2018 | 8 | 3 | 99999 | 1 | SMall
2018 | 9 | 2 | iu | 2 | IU
2018 | 10 | 15 | IU | . | Iu
;
run;
data want;
set have;
array var_num[*] _numeric_;
do i=3 to dim(var_num);
if var_num[i] = 99999 then var_num[i] = .;
end;
array var_cha[*] _character_;
do j=1 to dim(var_cha);
var_cha(j) = upcase(var_cha(j));
if var_cha[j] = 'YES' then var_cha[j] = 'Yes';
if var_cha[j] = 'NO' then var_cha[j] = 'No';
if var_cha[j] = 'IU' then var_cha[j] = 'IU';
if var_cha[j] = '99999' then var_cha[j] = 'IU';
if var_cha[j] = '' then var_cha[j] = 'IU';
end;
/* Integrate the code below into the loop*/
if &v4 = 'BIG' then &v4 = 'Big city';
if &v4 = 'SMALL' then &v4 = 'Small city';
if &v4 = 'IU' then &v4 = 'Unknow city size';
if &v4 = '99999' then &v4 = 'Unknow city size';
drop i j;
run;
我想如何编程的概念,
data want;
set have;
array var_cha[*] _character_;
do j=1 to dim(var_cha);
var_cha(j) = upcase(var_cha(j));
/* All of the if statements for the yes, no and IU */
if var_cha[j] = ColumnNumerOfVar4 then do;
/* where ColumnNumerOfVar4 is equal to the column number of var4*/
if var_cha[j] = 'BIG' then var_cha[j] = 'Big city';
if var_cha[j] = 'SMALL' then var_cha[j] = 'Small city';
if var_cha[j] = 'IU' then var_cha[j] = 'Unknow city size';
if var_cha[j] = '99999' then var_cha[j] = 'Unknow city size';
end;
end;
run;
答案 0 :(得分:2)
也许我不确定您想要的是什么,但是您似乎只是想用DO循环适用的变量名列表来创建一个宏变量,并使用它来定义数组。
%let yesnovars=var4 ;
array yesno &yesnovars;
然后您执行DO循环如下:
do j=1 to dim(yesno);
yesno(j) = upcase(yesno(j));
if yesno[j] = 'YES' then yesno[j] = 'Yes';
if yesno[j] = 'NO' then yesno[j] = 'No';
if yesno[j] = 'IU' then yesno[j] = 'IU';
if yesno[j] = '99999' then yesno[j] = 'IU';
if yesno[j] = '' then yesno[j] = 'IU';
end;
但实际上看起来您只想将格式应用于值。
因此,如果定义了$ YESNO格式和$ CITYSIZE格式,则可以执行以下操作将所有字符变量从原始值转换为格式化值。只需记住将它们定义足够长的时间即可容纳格式值,而不仅仅是原始值。
format var2 $yesno. var4 $citysize.;
array _c _character_;
do j=1 to dim(_c);
_c(j)=vvalue(_c(i));
end;
甚至更好地定义INformats并在读取原始数据时使用它们。
答案 1 :(得分:1)
如果需要获取数组中变量的名称,则可以使用vName函数:
Test_Gl(ItemNo).currency_amount = new CurrencyAmount
据我了解,这可以解决您的问题。但是,如果您还想获取特定变量的列号,则可以通过查看sasHelp.vColumns并将其放入宏变量中来实现。或在数据步骤的开头执行以下操作:
if (vName(var_cha[j]) = 'var4') then do;
/* where ColumnNumberOfVar4 is equal to the column number of var4*/
if var_cha[j] = 'BIG' then var_cha[j] = 'Big city';
if var_cha[j] = 'SMALL' then var_cha[j] = 'Small city';
if var_cha[j] = 'IU' then var_cha[j] = 'Unknow city size';
if var_cha[j] = '99999' then var_cha[j] = 'Unknow city size';
end;
但是我认为这不是您需要做的事情。