如何在SAS中删除多个列变量,这些列变量仅表示;空";但是你不是空白的吗?
如何删除SAS中的多个列变量,这些列变量仅状态为“Null”,但不为空?我创建了下表如何在SAS中删除多个列变量,这些列变量仅表示;空";但是你不是空白的吗?,sas,Sas,如何删除SAS中的多个列变量,这些列变量仅状态为“Null”,但不为空?我创建了下表 DATA test; INPUT name$ favourite_food$ occupation$ favourite_sport$; CARDS; John Null Nurse Null Michelle Null Lawyer Null Peter Null Teacher Null Kai Null Doctor Null run; 由于具有空值的列不是空的,因此我不确定如何删除这些列。我的分
DATA test;
INPUT name$ favourite_food$ occupation$ favourite_sport$;
CARDS;
John Null Nurse Null
Michelle Null Lawyer Null
Peter Null Teacher Null
Kai Null Doctor Null
run;
由于具有空值的列不是空的,因此我不确定如何删除这些列。我的分析不需要它们
我还知道我可以使用drop命令删除列。但是,当我有大约90个变量时,是否有更有效的方法删除多个“Null”变量需要对数据进行完整扫描,以检查所有列中的所有值。在扫描过程中,出现除
“Null”
以外的值将排除该列作为删除候选列
您可以使用一个临时数组来跟踪字符列名是什么,另一个数组设置为\u character\u
,以便可以在每一行中迭代这些列。该过程将构造一个列列表,可以根据您的条件删除这些列——该列表放置在宏符号表中,并可在后续代码中使用,以重写不包含这些列的数据,或在处理过程中使用数据集选项删除这些列
DATA test;
INPUT name$ favourite_food$ occupation$ favourite_sport$;
CARDS;
John Null Nurse Null
Michelle Null Lawyer Null
Peter Null Teacher Null
Kai Null Doctor Null
Zonker Null Null Null
run;
%let DROP_VARS=;
data _null_;
set test end=end;
array char_vars _CHARACTER_; * for iterating over values;
array null_vars (1000) $32 _temporary_ ; * for tracking column names;
* populate column name tracking array;
if _n_ = 1 then do;
do index = 1 to dim(char_vars);
null_vars(index) = vname(char_vars(index));
end;
end;
* scan each row, iterating over character variables;
* remove a column name from drop consideration when non "Null" occurs;
do index = 1 to dim(char_vars);
if not missing(null_vars(index)) then
if char_vars(index) ne "Null" then
null_vars(index) = '';
end;
* place space separated list of columns containing only "Null" in macro symbol table;
if end then
call symput('DROP_VARS', catx(' ', of null_vars(*)));
run;
* use macro variable as desired;
%put NOTE: &=DROP_VARS;
proc print data=test(drop=&DROP_VARS);
title "Non-null columns of TEST";
run;
data TEST2(label="Copy of Test, excluding null columns");
set TEST;
drop &DROP_VARS;
run;
还有许多其他SAS方法可以编写一个解决方案来删除具有相同值的列——向上搜索 需要对数据进行完整扫描,以检查所有列中的所有值。在扫描过程中,出现除
“Null”
以外的值将排除该列作为删除候选列
您可以使用一个临时数组来跟踪字符列名是什么,另一个数组设置为\u character\u
,以便可以在每一行中迭代这些列。该过程将构造一个列列表,可以根据您的条件删除这些列——该列表放置在宏符号表中,并可在后续代码中使用,以重写不包含这些列的数据,或在处理过程中使用数据集选项删除这些列
DATA test;
INPUT name$ favourite_food$ occupation$ favourite_sport$;
CARDS;
John Null Nurse Null
Michelle Null Lawyer Null
Peter Null Teacher Null
Kai Null Doctor Null
Zonker Null Null Null
run;
%let DROP_VARS=;
data _null_;
set test end=end;
array char_vars _CHARACTER_; * for iterating over values;
array null_vars (1000) $32 _temporary_ ; * for tracking column names;
* populate column name tracking array;
if _n_ = 1 then do;
do index = 1 to dim(char_vars);
null_vars(index) = vname(char_vars(index));
end;
end;
* scan each row, iterating over character variables;
* remove a column name from drop consideration when non "Null" occurs;
do index = 1 to dim(char_vars);
if not missing(null_vars(index)) then
if char_vars(index) ne "Null" then
null_vars(index) = '';
end;
* place space separated list of columns containing only "Null" in macro symbol table;
if end then
call symput('DROP_VARS', catx(' ', of null_vars(*)));
run;
* use macro variable as desired;
%put NOTE: &=DROP_VARS;
proc print data=test(drop=&DROP_VARS);
title "Non-null columns of TEST";
run;
data TEST2(label="Copy of Test, excluding null columns");
set TEST;
drop &DROP_VARS;
run;
还有许多其他SAS方法可以编写一个解决方案来删除具有相同值的列——向上搜索 proc freq中的
nlevels
选项返回每列中不同值的数量。因此,所有值相同的任何列的nlevel值均为1
如果您确信此规则仅适用于“Null”列,则可以使用此方法(即至少有两个不同的名称、职业等值)
nlevel
值不会自动包含在proc freq
的输出表中,因此您需要使用ods output
将列名放入表中。然后,您可以将它们分配给宏变量,以便在所使用的任何分析过程中的drop
语句中使用。或者,您可以按照要求在数据步骤中删除它们。(我通常倾向于前一种选择,以防有效数据被错误删除)
proc freq
中的nlevels
选项返回每列中不同值的数量。因此,所有值相同的任何列的nlevel值均为1
如果您确信此规则仅适用于“Null”列,则可以使用此方法(即至少有两个不同的名称、职业等值)
nlevel
值不会自动包含在proc freq
的输出表中,因此您需要使用ods output
将列名放入表中。然后,您可以将它们分配给宏变量,以便在所使用的任何分析过程中的drop
语句中使用。或者,您可以按照要求在数据步骤中删除它们。(我通常倾向于前一种选择,以防有效数据被错误删除)
这只是在宏中使用sql执行此操作的另一种方法。添加了详细的注释。 @longfish解决方案简单且非常有效
%macro abc;
/* picking up the variables on which Null check is needed*/
proc sql;
/*finding total number of obervations*/
select count(*) into :cnt from test;
select name into :name separated by '|' from dictionary.columns
where upcase(memname) = 'TEST'
and lowcase(name) like '%favourite_%';
/*creting temporary table to hold the values which should be dropped*/
create table temptable(col char(50),val num);;
/* looping through variables for which null check is needed*/
%do i = 1 %to %sysfunc(countw(&name, |));
%let col_val =%scan(&name,&i,|);
/* total obervations minus count for variables with null values gives 0
indicates that all are null values and are inseted in a temptable*/
proc sql;
insert into temptable
select col, val from
(select "&col_val" as col , &cnt- count(&col_val) as val
from test
where &col_val = "Null")
where val = 0;
%end;
/*picking up all the columns to be dropped*/
proc sql;
select col into :drop_columns separated by ' '
from temptable;
%put &drop_columns;
/* dropping the columns*/
data want;
set test(drop=&drop_columns);
run;
%mend;
%abc;
这只是在宏中使用sql执行此操作的另一种方法。添加了详细的注释。 @longfish解决方案简单且非常有效
%macro abc;
/* picking up the variables on which Null check is needed*/
proc sql;
/*finding total number of obervations*/
select count(*) into :cnt from test;
select name into :name separated by '|' from dictionary.columns
where upcase(memname) = 'TEST'
and lowcase(name) like '%favourite_%';
/*creting temporary table to hold the values which should be dropped*/
create table temptable(col char(50),val num);;
/* looping through variables for which null check is needed*/
%do i = 1 %to %sysfunc(countw(&name, |));
%let col_val =%scan(&name,&i,|);
/* total obervations minus count for variables with null values gives 0
indicates that all are null values and are inseted in a temptable*/
proc sql;
insert into temptable
select col, val from
(select "&col_val" as col , &cnt- count(&col_val) as val
from test
where &col_val = "Null")
where val = 0;
%end;
/*picking up all the columns to be dropped*/
proc sql;
select col into :drop_columns separated by ' '
from temptable;
%put &drop_columns;
/* dropping the columns*/
data want;
set test(drop=&drop_columns);
run;
%mend;
%abc;
对于这种情况,您有两种选择 第一,使用keep。 keep函数保留您想要的变量,因此如果您已经知道除NULL以外的变量,只需输入keep,例如: 数据测试(保持=喜爱的食物职业) 运行 如果你知道最喜欢的食物和职业不是空的 第二,使用删除功能示例: 数据测试
INPUT name$ favourite_food$ occupation$ favourite_sport$;
CARDS;
if name eq NULL then delete;
运行
祝你好运 对于这种情况,您有两种选择 第一,使用keep。 keep函数保留您想要的变量,因此如果您已经知道除NULL以外的变量,只需输入keep,例如: 数据测试(保持=喜爱的食物职业) 运行 如果你知道最喜欢的食物和职业不是空的 第二,使用删除功能示例: 数据测试
INPUT name$ favourite_food$ occupation$ favourite_sport$;
CARDS;
if name eq NULL then delete;
运行
祝你好运