如何在SAS中删除多个列变量,这些列变量仅表示;空";但是你不是空白的吗?

如何在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; 由于具有空值的列不是空的,因此我不确定如何删除这些列。我的分

如何删除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;
由于具有空值的列不是空的,因此我不确定如何删除这些列。我的分析不需要它们


我还知道我可以使用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;
运行

祝你好运