以下是简单的SAS程序:
data mydata;
do group = 'placebo', 'active';
do subj = 1 to 5;
input score @;
output;
end;
end;
datalines;
250 222 230 210 199
166 183 123 129 234
;
我自己在学习SAS。所以我想要确定这里发生了什么。据我了解,5个条目的第一行属于安慰剂组,第二行属于活跃组。首先,输入缓冲区包含5个数字的第一行,do subj = 1到5逐个打印出来,直到当前数据步骤迭代结束。然后,数据步骤继续第二次迭代。这种理解是否正确?非常感谢您的时间和关注。
PS。我只是想确保何时释放当前的输入缓冲区。在线查看后,我发现@的目的如下:
在DATA步骤的同一次迭代中保存用于执行下一个INPUT语句的输入记录。这个行保持说明符称为尾随@。
因此,这意味着如果满足以下两个条件之一,则释放输入缓冲区:
(1):在没有任何@或@@的情况下满足新的输入声明。 (2):当前数据步骤迭代的结束。
非常感谢任何评论。
答案 0 :(得分:1)
我喜欢汤姆的回答,但想要扩展一下数据步迭代的含义。你写道:
首先,输入缓冲区包含5个数字的第一行,do subj = 1到5逐个打印出来,直到当前数据步骤迭代结束。然后,数据步骤继续第二次迭代。这种理解是否正确?
DATA步骤是一个隐含的迭代循环,从顶部(DATA语句)到底部(通常是RUN语句,在这种情况下我认为是DATALINES语句)。如果要查看循环的每次迭代会发生什么,可以使用PUT语句将值写入日志,也可以将 N 写入日志,这是DATA步骤迭代的计数器数。因此,您可以将代码更改为:
do group = 'placebo', 'active';
do subj = 1 to 5;
input score @;
put _n_= score= ;
output;
end;
end;
如果这样做,您应该看到所有数据(两行中的所有10个值)都在DATA步骤的第一次迭代中处理。您应该只在日志中看到_n_=1
。正如@Tom解释的那样,这是因为在您编写的显式循环中,当SAS无法在第一行找到第六个值时,SAS会前进到第二行数据。我想大多数人都会认为NOTE SAS会因为警告甚至错误而转移到下一行。
如果您希望对DATA步骤循环进行两次迭代,则可以更改为:
if _n_=1 then group = 'placebo';
else if _n_=2 then group= 'active';
do subj = 1 to 5;
input score @;
put _n_= score= ;
output;
end;
(并不是说两次迭代更好,或者上面的代码更好,点只是为了显示迭代的数据步骤)。
答案 1 :(得分:0)
您的代码应该可以正常工作,但是您应该看到SAS在LOG中转到新行的注释。
当GROUP ='安慰剂'内部循环(DO SUBJ ...)将读取5个数字并将指针留在第一行的末尾。然后外循环将再次执行GROUP =' active'。当它试图读取SUBJ = 1的SCORE时,第一行没有任何东西。所以SAS将跳到下一行并从那里读取第一个SCORE。然后从该行读取其他四个值。
最后,在数据步骤结束时,它将"发布"该行使指针位于第三行的开头(如果有第三行)。
然后整个数据步骤将循环一次并设置GROUP ='安慰剂'和SUBJ = 1,但是当它尝试读取SCORE时,它会读取文件的末尾并停止数据步骤。
请注意,只要您将10个值间隔在您想要的任意数量的行上,您的程序就可以正常工作。