If statement SAS错误:SUM的Null参数无效
因此,我有一个名为table1的数据,如下所示:If statement SAS错误:SUM的Null参数无效,if-statement,sas,sas-macro,datastep,If Statement,Sas,Sas Macro,Datastep,因此,我有一个名为table1的数据,如下所示: Obs ID M_201812 M_201901 M_201902 M_201903 1 X1 1 . . . 2 X2 1 1 . . 3 X3 . 1 1 . 4 X4 .
Obs ID M_201812 M_201901 M_201902 M_201903
1 X1 1 . . .
2 X2 1 1 . .
3 X3 . 1 1 .
4 X4 . 1 . .
5 X5 . 1 . .
6 X6 1 . . .
7 X7 1 1 . .
8 X8 1 1 . .
9 X9 . . 1 .
10 X10 1 1 . .
M_201812,M_201901,M_201902,M_201903
这里的每一列都是一个月,它是根据以前运行的一些宏动态生成的。月份将是动态的,并且会有所不同。我需要做的是计算过去3个月、6个月和12个月的总和。我的想法是:
A将列名存储在宏变量中:
proc sql noprint;
select distinct name
into :cols2 separated by ','
from dictionary.columns
where upcase(memname) = 'Table1' and name not in ('ID');
;
quit;
%put &cols2.
data table1;
set table1;
if count("&cols2",",") <=3 then do;
3m_total=sum(of &cols2);
6m_total=sum(of &cols2);
12m_total=sum(of &cols2);
end;
else if 3< count("&cols2",",") <=6 then do;
3m_total=sum(%scan(%superQ(cols2),-1,%str(,)),%scan(%superQ(cols2),-2,%str(,)),%scan(%superQ(cols2),-3,%str(,)));
6m_total=sum(of &cols2);
12m_total=sum(of &cols2);
end;
else if 6< count("&cols2",",") <=12 then do;
3m_total=sum(%scan(%superQ(cols2),-1,%str(,)),%scan(%superQ(cols2),-2,%str(,)),%scan(%superQ(cols2),-3,%str(,)));
6m_total=sum(%scan(%superQ(cols2),-1,%str(,)),%scan(%superQ(cols2),-2,%str(,)),%scan(%superQ(cols2),-3,%str(,)),%scan(%superQ(cols2),-4,%str(,)),%scan(%superQ(cols2),-5,%str(,)),%scan(%superQ(cols2),-6,%str(,)));
12m_total=sum(of &cols2);
else do;
3m_total=sum(%scan(%superQ(cols2),-1,%str(,)),%scan(%superQ(cols2),-2,%str(,)),%scan(%superQ(cols2),-3,%str(,)));
6m_total=sum(%scan(%superQ(cols2),-1,%str(,)),%scan(%superQ(cols2),-2,%str(,)),%scan(%superQ(cols2),-3,%str(,)),%scan(%superQ(cols2),-4,%str(,)),%scan(%superQ(cols2),-5,%str(,)),%scan(%superQ(cols2),-6,%str(,)));
12m_total=sum(%scan(%superQ(cols2),-1,%str(,)),%scan(%superQ(cols2),-2,%str(,)),%scan(%superQ(cols2),-3,%str(,)),%scan(%superQ(cols2),-4,%str(,)),%scan(%superQ(cols2),-5,%str(,)),%scan(%superQ(cols2),-6,%str(,)),
%scan(%superQ(cols2),-7,%str(,)),%scan(%superQ(cols2),-8,%str(,)),%scan(%superQ(cols2),-9,%str(,)),%scan(%superQ(cols2),-10,%str(,)),%scan(%superQ(cols2),-11,%str(,)),%scan(%superQ(cols2),-12,%str(,)));
end;
run;
产出如下:
Obs ID M_201812 M_201901 M_201902 M_201903
1 X1 1 . . .
2 X2 1 1 . .
3 X3 . 1 1 .
4 X4 . 1 . .
5 X5 . 1 . .
6 X6 1 . . .
7 X7 1 1 . .
8 X8 1 1 . .
9 X9 . . 1 .
10 X10 1 1 . .
M_201812,M_201901,M_201902,M_201903
B根据变量中的项目数创建金额:
proc sql noprint;
select distinct name
into :cols2 separated by ','
from dictionary.columns
where upcase(memname) = 'Table1' and name not in ('ID');
;
quit;
%put &cols2.
data table1;
set table1;
if count("&cols2",",") <=3 then do;
3m_total=sum(of &cols2);
6m_total=sum(of &cols2);
12m_total=sum(of &cols2);
end;
else if 3< count("&cols2",",") <=6 then do;
3m_total=sum(%scan(%superQ(cols2),-1,%str(,)),%scan(%superQ(cols2),-2,%str(,)),%scan(%superQ(cols2),-3,%str(,)));
6m_total=sum(of &cols2);
12m_total=sum(of &cols2);
end;
else if 6< count("&cols2",",") <=12 then do;
3m_total=sum(%scan(%superQ(cols2),-1,%str(,)),%scan(%superQ(cols2),-2,%str(,)),%scan(%superQ(cols2),-3,%str(,)));
6m_total=sum(%scan(%superQ(cols2),-1,%str(,)),%scan(%superQ(cols2),-2,%str(,)),%scan(%superQ(cols2),-3,%str(,)),%scan(%superQ(cols2),-4,%str(,)),%scan(%superQ(cols2),-5,%str(,)),%scan(%superQ(cols2),-6,%str(,)));
12m_total=sum(of &cols2);
else do;
3m_total=sum(%scan(%superQ(cols2),-1,%str(,)),%scan(%superQ(cols2),-2,%str(,)),%scan(%superQ(cols2),-3,%str(,)));
6m_total=sum(%scan(%superQ(cols2),-1,%str(,)),%scan(%superQ(cols2),-2,%str(,)),%scan(%superQ(cols2),-3,%str(,)),%scan(%superQ(cols2),-4,%str(,)),%scan(%superQ(cols2),-5,%str(,)),%scan(%superQ(cols2),-6,%str(,)));
12m_total=sum(%scan(%superQ(cols2),-1,%str(,)),%scan(%superQ(cols2),-2,%str(,)),%scan(%superQ(cols2),-3,%str(,)),%scan(%superQ(cols2),-4,%str(,)),%scan(%superQ(cols2),-5,%str(,)),%scan(%superQ(cols2),-6,%str(,)),
%scan(%superQ(cols2),-7,%str(,)),%scan(%superQ(cols2),-8,%str(,)),%scan(%superQ(cols2),-9,%str(,)),%scan(%superQ(cols2),-10,%str(,)),%scan(%superQ(cols2),-11,%str(,)),%scan(%superQ(cols2),-12,%str(,)));
end;
run;
这发生在最后一个else do语句中。我一辈子都不明白为什么sas不能阅读一个简单的if-then-do-else语句。if条件或调用宏变量时是否有错误?这里的任何帮助都将不胜感激。非常感谢。如果看不到宏逻辑实际生成的代码,很难判断。 但很可能是因为生成的两个逗号之间没有逗号,如下所示:
475 data test;
476 y=sum(1,,2,3);
-
159
ERROR 159-185: Null parameters for SUM are invalid.
477 run;
您需要要么不生成额外的逗号,要么在逗号之间加上一些东西。因此,要么是缺少值的句点,要么是0
通常,如果不使用逗号,SAS会更容易。因此,获取一个以空格分隔的变量名列表
proc contents data=Table1 noprint
out=_contents (where=(name ne 'ID'))
;
run;
proc sql noprint;
select name
, case when (varnum>9) then name else ' ' end
, case when (varnum>6) then name else ' ' end
, case when (varnum>3) then name else ' ' end
into :cols_12 separated by ' '
, :cols_3 separated by ' '
, :cols_6 separated by ' '
, :cols_9 separated by ' '
from _contents
order by name
;
quit;
然后使用of关键字使用名称列表,这样它们之间就不需要逗号了
data want;
set table1;
total_3m=sum(0,of &cols_3);
total_6m=sum(0,of &cols_6);
total_9m=sum(0,of &cols_9);
total=sum(0,of &cols_12);
run;
还要记住为变量使用有效的名称。变量名不能以数字开头。请考虑将数据从宽改为长,然后对3/6/12个月的运行总和运行多个相关的聚合SQL子查询。这将达到您提到的预期结果: 我需要做的是计算过去3个月、6个月和12个月的总和 资料 重塑 聚集 proc-sql; 创建表Run_Sums作为 选择m.ID, m、 月日, m、 价值观, 选择总和值 从月份\u数据\u长sub 其中sub.ID=m.ID 和次月日>=intnx'Month',m.Month\u Date,-3 子月日=intnx'Month',m.Month\u Date,-6 子月日=intnx'Month',m.Month\u Date,-12
你为什么要从这个结构开始呢?你不能从垂直结构开始,其中日期是变量的值,而不是变量的名称吗?重复@Tom,这是一个报告结构,不是一个维护或计算数据的好结构。这是可以做到的,但却是一件痛苦的事情。具体地说,回显@Reeza时,您应该使用MM/YYY列保持数据的长度,而不是宽度,这对几乎任何分析都有很大帮助。见proc转置。谢谢汤姆的建议。我运行了你的代码。但也有一些例子,我注意到一些ID错误地填充了总共300万、600万、1200万个ID。例如:对于给定表格中的ID X8,他的3m总数应该是1从201901到201903,他的6个月总数应该是2从任何可用到201903。但碰巧我得到了1,总共3米和6米。如果有解决办法,一定要告诉我。如果变量未按时间顺序定义,则如何选择哪些变量不起作用的逻辑。查看宏变量和_内容数据集的值以了解发生了什么。也许可以将keep=M_20:datastep选项添加到proc内容的输入中,以仅列出与您的模式匹配的变量。但是对于一个更健壮的解决方案,你真的应该将日期保存在数据中,而不是变量名中,这样逻辑就容易多了。谢谢Tom,我将尝试编辑它。最后一个问题。在一个基本的数据步骤中,如果我运行的扫描函数超出了字符串的长度范围,是否有办法终止该进程?假设我有一个单词编码,我运行Scancoding,10-它将是空的。但我不想让它执行任何事情。可能?有关扫描和%SCAN的问题在某些方面完全不同。在普通SAS代码中,您可以测试扫描是否只返回空格并采取一些操作。但在您的示例中,您使用%SCAN生成SAS代码,然后将对其进行编译。如果希望根据%SCAN返回的结果有条件地生成不同的代码,则需要宏逻辑,这通常意味着实际的宏。虽然使用%sysfuncifc。。。。在某些情况下可以在开放代码中使用。谢谢冻糕!我试试看。