使用IN()函数评估变量

时间:2019-03-07 18:28:12

标签: sql function variables sas

我正在尝试解析in()函数中的datastep变量。我有一个数据集,如下所示:

|Run|Sample Level|Samples Tested|
| 1 |     1      |      1-5     |
| 1 |     2      |      1-5     |
...etc
| 1 |     5      |      1-5     |
---------------------------------
| 2 |     1      |      1-4     |
| 2 |     2      |      1-4     |

测试样品随运行而变化。通常,数据集中唯一的样本级别是“样本测试”提供的范围内的那些。但是,有时情况并非如此,并且可能变得凌乱。例如,我研究的最后一个看起来像这样:

|Run|Sample Level|Samples Tested|
| 1 |      1     |2-9, 12-35, 37-40|

在这种情况下,我想删除所有包含未包含在“测试样品”中的样品水平的行,这是通过手动添加代码来完成的:

Data Want;
set Have;
if sample_level not in (2:9, 12:35, 37:40) then delete;
run;

但是我想做的是通过查看“测试样本”列自动完成此操作。将“-”转换为“:”很容易,但是我遇到的困难是让IN()函数识别或解析变量。我想要看起来像这样的代码:if sample_level not in(Samples_Tested) then delete;,其中samples_tested已转换为IN()函数可以处理的东西。如果有人有他们认为可行的解决方案,我也不反对使用proc sql;。我知道您可以做

之类的事情
Proc sql; Create table want as select * from HAVE where Sample_Level in (Select Samples_Tested from Have); Quit;

但是问题是测试的样品随运行而变化,并且可能有16种不同的运行。希望我已经足够清楚地说明了挑战。感谢您抽出宝贵的时间阅读本文,并提前感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

假设对于每个RUN值,SAMPLES_TESTED的值都是恒定的,则可以使用它来生成选择标准。例如,您可以使用_null_数据步骤将WHERE语句写入文件,然后将该代码%include到另一个数据步骤中。

filename code temp;
data _null_;
  file code;
  if eof then put ';';
  set have end=eof;
  by run;
  if first.run;
  if _n_=1 then put 'where ' @ ;
  else put '   or ' @ ;
  samples_tested=translate(samples_tested,':','-');
  put '(' run= 'and sample_level in (' samples_tested '))';
run;
data want;
  set have;
  %include code;
run;

注意:IN是运算符,而不是函数。

答案 1 :(得分:0)

很高兴看到SAS代码;-)

这将适用于一个范围:

select * from HAVE where level in (tested);

对于多个范围,我将在MySQL中使用SUBSTRING_INDEX或仅将SUBSTRING和INDEX结合使用以查找下一个条件。     从(已测试(1)中的水平或(已测试2)中的水平或(已测试3)中的水平)中选择*; 例如,在其中将tested1替换为substr(tested,1,index(tested,',')

我使用以下代码生成示例:     创建表有     (运行int,      级别int      经测试的varchar(20));      INSERT INTO拥有(运行,级别,测试)     值(1、1,“ 3-5”);     INSERT INTO拥有(运行,级别,测试)     值(1、3,“ 3-5、12:35”);     INSERT INTO拥有(运行,级别,测试)     值(1、20,“ 3-5、12-35”);