SAS:如何在数据行上循环宏以更改为丢失
SAS: How to loop a macro over rows of data to change to missing
任何人都可以帮助解决我遇到的这个问题,其中宏只获取数据的最后一行值吗?
我有一些数据如下所示:
data data1 ;
infile datalines dsd dlm='|' truncover;
input id :. year_age_15 EDU_2000 EDU_2001 EDU_2002 ;
datalines4;
10|2000|3|4|5
11|2000|5|5|6
12|2001|1|2|3
13|2002|5|5|6
14|2001|2|2|2
15|2000|3|3|4
;;;;
但是我需要它使用年份变量来确定要保留哪些数据,然后将该值之后的年份的所有值更改为缺失,如下所示:
data data1 ;
infile datalines dsd dlm='|' truncover;
input id :. year_age_15 EDU_2000 EDU_2001 EDU_2002 ;
datalines4;
10|2000|3|.|.
11|2000|5|.|.
12|2001|1|2|.
13|2002|5|5|6
14|2001|2|2|.
15|2000|3|.|.
;;;;
我一直在努力让这个宏起作用,但它只能间歇性地起作用,并且只对数据的最后一行起作用,而不是循环遍历这些行。
%macro macro2 (output=, input=);
data &output;
set &input;
%DO I = 1 %TO 6;
%do; call symput('value2',trim(left(put(year_age_15,8.))));
temp_col=&value2.;
%let year_end=&value2.;
%put YEAR END IS: &year_end.;
%put EDU YEAR IS: EDU_&year_end.;
%do year = &year_end. %TO 2002;
%put &year.;
EDU_&year.=.;
%end;
%end;
%end;
run;
%MEND macro2;
%macro1(input=testset, output=output_testset);
在 R 中,它可能是一些简单的东西,例如:
对于(我在 1:6){。
这样做
}
有什么建议吗?我不知道哪位出了问题,谢谢!
创建一个数组并按年份而不是默认值对其进行索引1:n
从 year+1 开始遍历数组并设置为 missing
data want;
set data1;
array educ(2000:2002) edu_2000-edu_2002;
if (year_age_15 +1) <= hbound(educ) then do i= (year_age_15 +1) to hbound(educ);
call missing(educ(i));
end;
run;
所以,我认为这里的问题是您的数据处于错误的级别。你当然可以按照 Reeza 的建议去做,我认为这样做可能是合理的,但是这有点复杂的原因是你的变量名中有数据。这不是最佳做法 - 您的变量名称应该是“教育”,并且您的数据每年应该有一行。那么这将是一个简单的 WHERE 语句!
这里有一个简单的 PROC TRANSPOSE
可以将其转换为正确的结构,然后如果您真的需要另一种方式,第二个将把它转换回来。 where
语句可以在 proc transpose
中,也可以在其他地方使用。
proc transpose data=data1 out=data_t (where=(year_Age_15 ge input(scan(_NAME_,2,'_'),4.)));
by id year_Age_15;
var edu_:;
run;
proc transpose data=data_t out=want;
by id year_age_15;
id _name_;
var col1;
run;
正如@Joe 提到的那样,要匹配的年份是变量名称的一部分,它会引起震颤 'data in the metadata'
您可以使用 VNAME
检索索引访问的数组元素的变量名。使用该功能与预期的变量名称进行比较,同时根据名为 EDU*
.
的变量循环遍历 变量数组
示例:
data have ;
infile datalines dsd dlm='|' truncover;
input id :. year_age_15 EDU_2000 EDU_2001 EDU_2002 ;
datalines4;
10|2000|3|4|5
11|2000|5|5|6
12|2001|1|2|3
13|2002|5|5|6
14|2001|2|2|2
15|2000|3|3|4
;;;;
data want;
set have;
array edus edu_:;
* find index of element corresponding to variable name having year;
do _n_ = 1 to dim(edus) until (upcase(vname(edus(_n_))) = cats('EDU_',year_age_15));
end;
* fill in elements at indices post the found one with missing values;
do _n_ = _n_+1 to dim(edus);
call missing(edus(_n_));
end;
run;
任何人都可以帮助解决我遇到的这个问题,其中宏只获取数据的最后一行值吗?
我有一些数据如下所示:
data data1 ;
infile datalines dsd dlm='|' truncover;
input id :. year_age_15 EDU_2000 EDU_2001 EDU_2002 ;
datalines4;
10|2000|3|4|5
11|2000|5|5|6
12|2001|1|2|3
13|2002|5|5|6
14|2001|2|2|2
15|2000|3|3|4
;;;;
但是我需要它使用年份变量来确定要保留哪些数据,然后将该值之后的年份的所有值更改为缺失,如下所示:
data data1 ;
infile datalines dsd dlm='|' truncover;
input id :. year_age_15 EDU_2000 EDU_2001 EDU_2002 ;
datalines4;
10|2000|3|.|.
11|2000|5|.|.
12|2001|1|2|.
13|2002|5|5|6
14|2001|2|2|.
15|2000|3|.|.
;;;;
我一直在努力让这个宏起作用,但它只能间歇性地起作用,并且只对数据的最后一行起作用,而不是循环遍历这些行。
%macro macro2 (output=, input=);
data &output;
set &input;
%DO I = 1 %TO 6;
%do; call symput('value2',trim(left(put(year_age_15,8.))));
temp_col=&value2.;
%let year_end=&value2.;
%put YEAR END IS: &year_end.;
%put EDU YEAR IS: EDU_&year_end.;
%do year = &year_end. %TO 2002;
%put &year.;
EDU_&year.=.;
%end;
%end;
%end;
run;
%MEND macro2;
%macro1(input=testset, output=output_testset);
在 R 中,它可能是一些简单的东西,例如:
对于(我在 1:6){。
这样做
}
有什么建议吗?我不知道哪位出了问题,谢谢!
创建一个数组并按年份而不是默认值对其进行索引1:n
从 year+1 开始遍历数组并设置为 missing
data want; set data1; array educ(2000:2002) edu_2000-edu_2002; if (year_age_15 +1) <= hbound(educ) then do i= (year_age_15 +1) to hbound(educ); call missing(educ(i)); end; run;
所以,我认为这里的问题是您的数据处于错误的级别。你当然可以按照 Reeza 的建议去做,我认为这样做可能是合理的,但是这有点复杂的原因是你的变量名中有数据。这不是最佳做法 - 您的变量名称应该是“教育”,并且您的数据每年应该有一行。那么这将是一个简单的 WHERE 语句!
这里有一个简单的 PROC TRANSPOSE
可以将其转换为正确的结构,然后如果您真的需要另一种方式,第二个将把它转换回来。 where
语句可以在 proc transpose
中,也可以在其他地方使用。
proc transpose data=data1 out=data_t (where=(year_Age_15 ge input(scan(_NAME_,2,'_'),4.)));
by id year_Age_15;
var edu_:;
run;
proc transpose data=data_t out=want;
by id year_age_15;
id _name_;
var col1;
run;
正如@Joe 提到的那样,要匹配的年份是变量名称的一部分,它会引起震颤 'data in the metadata'
您可以使用 VNAME
检索索引访问的数组元素的变量名。使用该功能与预期的变量名称进行比较,同时根据名为 EDU*
.
示例:
data have ;
infile datalines dsd dlm='|' truncover;
input id :. year_age_15 EDU_2000 EDU_2001 EDU_2002 ;
datalines4;
10|2000|3|4|5
11|2000|5|5|6
12|2001|1|2|3
13|2002|5|5|6
14|2001|2|2|2
15|2000|3|3|4
;;;;
data want;
set have;
array edus edu_:;
* find index of element corresponding to variable name having year;
do _n_ = 1 to dim(edus) until (upcase(vname(edus(_n_))) = cats('EDU_',year_age_15));
end;
* fill in elements at indices post the found one with missing values;
do _n_ = _n_+1 to dim(edus);
call missing(edus(_n_));
end;
run;