SAS:如果列具有数组中的值

时间:2014-12-04 06:07:42

标签: arrays if-statement sas

以下是我正在做的事情的一个例子。我想得到数据集的子集(即在Alphabet列中包含这些字母的行)。我想只选择那些Transport_company是现代,丰田或福特的记录。

Data arrayInIf;
set OldTable;
array Car_array {3}a b c('Hyundai', 'Toyota', 'Ford');
If Transport_company ^= Car_array
Then
    Delete;
Run;

什么错了?我怎样才能让它发挥作用。

好的,所以样本数据是:

  • Zip Transport_Company No. Sold
  • 12345 Hyundai 10
  • 90145 NASA 50
  • 20202 Toyota 30
  • 40002 Harley Davidson 5
  • 10000 Ford 15

所以,我只想保留与汽车公司相关的所有行

2 个答案:

答案 0 :(得分:1)

我认为你不需要在这里使用数组。如果您只想根据多个值选择行,请使用in关键字。 SAS中的数组概念与其他一些编程语言不同,后者通常将数组视为一组字符串和数值。 SAS中的数组存储一组列(变量)。

data b;
set a;
where Transport_Company in ('Hyundai', 'Toyota', 'Ford');
run;

输出:

   Obs     Zip      Transport_Company     Sold
    1     12345     Hyundai               10
    2     20202     Toyota                30
    3     10000     Ford                  15

正如@alex在评论中提到的,如果您需要根据长列表过滤行,where...in ()将变得很麻烦。在这种情况下,我的解决方案通常是创建一个包含这些名称的新集。

Transport_Company

Hyundai
Toyota
Ford
...
BMW

然后使用proc sql进行简单的伪合并(条件选择)。这应该相当快。

proc sql;
    create table c as
    select a.* from a, cars where a.Transport_Company = cars.Transport_Company;
quit;

答案 1 :(得分:1)

罗比是对的,如果你的数据已不在数组中,你就不应该使用数组方法,因为它会增加额外的复杂性 - 很好。

但是,如果 已经在数组中,那么whichc(或数字的whichn)是一个很好的解决方案。

data oldtable;
input Zip Transport_Company $ No_Sold;
datalines;
12345 Hyundai 10
90145 NASA 50
20202 Toyota 30
40002 HarleyDavidson 5
10000 Ford 15
;;;;
run;

Data arrayInIf;
  set OldTable;
  array Car_array{3} $ ('Hyundai', 'Toyota', 'Ford');
  If whichc(transport_company,of car_array[*])=0
  Then
    Delete;
Run;

通常,最佳方法是构建格式。从数据集中查找PROC FORMAT CNTLIN如何执行此操作;或者您可以在代码中执行此操作:

proc format;
  value $automakerF
    'Hyundai','Toyota','Ford'=1
    other=0;
quit;

data fmtInIf;
  set oldtable;
  if put(transport_company,automakerF.) ne '1' 
    then delete;
 run;

这具有将数据与代码分离的价值,如果需要,还可以从数据集中引入汽车制造商名称;同样,您也可以采用一种格式来完成所有不同的行业。它也非常快,比一堆if语句或in语句更快。