2013-04-23 3 views
5

Как создать набор данных SAS из другого набора данных, используя только последние n наблюдений из исходного набора данных. Это легко, когда вы знаете значение n. Если я не знаю «n», как это можно сделать?SAS - Как получить последние наблюдения «n» из набора данных?

+1

Что значит, вы не знаете 'n'? Как вы узнаете значение «n» - это переменная набора данных, макропеременная, параметр? – Joe

ответ

8

Предполагается, что у вас есть макропеременная, в которой указано, сколько наблюдений вы хотите. NOBS сообщает вам количество наблюдений в наборе данных в настоящее время, не читая всего этого.

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

Используя пример Джо макроскопически переменной, чтобы указать количество наблюдений вы хотите, вот еще один ответ:

%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

+3

@Joe Представьте набор данных с 1 миллионом обьем, и вы хотите «последний» 10. Используя этот метод, выполняются только 10 «входных» операций. Использование только значения NOBS требует 1 миллион операций ввода. В зависимости от того, насколько «широкий» набор данных, это различие может быть очень значительным. – BellevueBob

+1

Правильно, я, конечно, вижу возможность для этого быстрее. Мне любопытно, в какой момент это быстрее/медленнее (т. Е. Какой размер набора данных, какой% данных вытягивается - 10 из 1MM, конечно, будет быстрее, но как насчет 500k от 1MM?) – Joe

1

Ради разнообразия, здесь другой подход (не обязательно лучше один)

%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

2

Если набор данных велик, вы не можете прочитать весь набор данных. Вместо этого вы можете попробовать конструкцию, которая сначала считывает общее количество наблюдений в наборе данных. Поэтому, если вы хотите получить последние наблюдения:

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; 
Смежные вопросы