SAS - 如何从数据集中获取最后的'n'观察值?

问题描述:

如何仅使用来自原始数据集的最后n个观测值从另一个数据集创建SAS数据集。当你知道n的值时,这很容易。如果我不知道'n'这个怎么做?SAS - 如何从数据集中获取最后的'n'观察值?

+1

你是什么意思你不知道“n”不?你如何找出'n'的值 - 它是一个数据集变量,一个宏变量,一个参数? – Joe 2013-04-23 13:58:27

这假定您有一个宏变量,表示您需要多少个观测值。 NOBS告诉你目前数据集中的观测数量没有读取整个数据。

%let obswant=5; 
data want; 
set sashelp.class nobs=obscount; 
if _n_ gt (obscount-&obswant.); 
run; 

使用宏变量的乔的例子来指定要观测的数量,这里是另一个答案:

%let obswant = 10; 
data want; 
    do _i_=nobs-(&obswant-1) to nobs; 
     set have point=_i_ nobs=nobs; 
     output; 
     end; 
    stop; /* Needed to stop data step */ 
run; 

这应该有更好的表现,因为它只读取需要的具体意见。

+0

我很好奇“这应该表现更好”的条件。我怀疑它是每一个;随机存取速度不如顺序存取速度快,所以存在一定的损失。如果我有一些时间,可以测试一下。我怀疑,如果你使用大多数观察,它会按顺序进行更快,但如果它是一个大型数据集,并且你需要少量的观察,那么执行random = access会更快。让我希望SAS能够以相反的顺序打开一个数据集,而不必先排序。 – Joe 2013-04-23 14:52:52

+3

@Joe想象一个拥有100万obs的数据集,你想要“最后一个”10.使用这种技术,只有10个“输入”操作被执行。仅使用NOBS值就需要100万次“输入”操作。取决于数据集的“宽度”,这种差异可能非常显着。 – BellevueBob 2013-04-23 14:59:10

+1

对,我当然看到这个速度更快的可能性。我很好奇它在哪一点上更快/更慢(例如,数据集的大小,所拉取数据的百分比 - 从1MM的10个数据当然会更快,但从1MM大概是500k呢?) – Joe 2013-04-23 16:16:40

对于各种各样的缘故,这里的另一种方法(不一定是更好的一个)

%let obswant=5; 

proc sql noprint; 
select nlobs-&obswant.+1 into :obscalc 
from dictionary.tables 
where libname='SASHELP' and upcase(memname)='CLASS'; 
quit; 

data want; 
set sashelp.class (firstobs=&obscalc.); 
run; 
+1

注意:您要指定格式时使用select..into,否则该值被格式化为BEST8。,当您选择一个大于或等于100,000,000的值时(这会导致四舍五入的格式化),导致出现奇怪的错误。 – Nickolay 2013-05-01 03:59:45

如果数据集很大,你可能不想读取整个数据集。相反,您可以尝试一种构造,首先读取数据集中观察的总数。所以,如果你想有最后意见:

data t; 
    input x; 
datalines; 
1 
2 
3 
4 
; 

%let dsid=%sysfunc(open(t)); 
%let num=%sysfunc(attrn(&dsid,nlobs)); 
%let rc=%sysfunc(close(&dsid)); 
%let number = 2; 

data tt; 
set t (firstobs = %eval(&num.-&number.+1)); 
run;