2014-01-10 2 views
1

Я очень, очень новичок в SAS и читал вопросы о стеке и документации SAS, чтобы написать код для очень конкретной цели. Мне было трудно достичь моей цели и понять SAS по двум причинам: я могу выполнять код только на удаленном сервере, хотя SSH, потому что у меня нет SAS локально (поэтому при каждом изменении мне нужно загрузить файл, выполнить и верните файлы журнала и lst, проверьте наличие ошибок), и большинство вводных тем, которые я прочитал, не сразу применимы к моей задаче (меня интересует только использование SAS для автоматизации определенной процедуры извлечения данных).Ошибка в наборе данных firstobs

Моя цель состоит в том, чтобы:

  • чтения определенных линеечки (т.е. идентификатор для запаса) на файл CSV;
  • цикл каждого тикера, получая необходимую информацию через определенные макросы.

До сих пор мне удалось прочитать CSV и импортировать эти данные в набор данных. Чтобы проверить, правильно ли работают основы того, что мне нужно, я сделал следующий код. Моя цель состояла в цикле, чтобы присвоить тикер определенной «переменной» currentticker (возможно, не правильному имени для нее) и распечатать ее. В файле csv есть только две строки: «Первая» и «DELL» - в другой.

libname mydir '~/'; 

data companies; 
    infile 'sastests/data/tickers.csv' delimiter=','; 
    input ticker $; 
run; 

proc sql; 
select count(*) 
into  :OBSCOUNT 
from  companies; 
quit; 

proc print data=companies; 
    var ticker; 
run; 

%do iter = 1 to &OBSCOUNT; 
    data currentticker; 
    set companies (firstobs = iter obs = iter); 
    run; 
    proc print data = currentticker; 
    run; 
%end; 

Когда я просматриваю файл журнала, я сразу же получаю сообщение об ошибке в опции firstobs набора данных.

Invalid value for the FIRSTOBS option. 

Почему это так? Не должно ли оно быть числом, таким образом, действующим как FIRSTOBS?

Благодарим вас за это заранее.

Редактировать 1: Заголовок не было хорошим описанием проблемы.

Редактировать 2: Примеры макросов, которые будут использоваться для одного тикера. Поиск должен быть отправлен с кодом &. lookup будет вызываться, затем getopt и, наконец, export_tab. Этот код не относится к моему авторству, я немного изменил его после того, как он был представлен в качестве образца кода WRDS.

%macro lookup; 

    data idcodes (keep=secid); 
    set optionm.secnmd; 
    where lowcase(ticker) = &ticker; 

    proc sort data=idcodes nodupkey; 
    by secid; 

    proc print data=idcodes; 

%mend; 

%macro getopt(year); 

    proc sql; 
    create table temp as 
     select a.* 
     from 
     optionm.vsurfd&year as a, 
     idcodes as b 
     where 
     a.secid = b.secid; 
    run; 

    proc datasets; 
    append base=work.&outputfile 
    data=work.temp; 
    run; 

%mend; 

%macro export_tab; 

    proc export data=&outputfile outfile="&outputfile._out.txt" dbms=tab replace; 
    run; 

%mend; 
+0

Что вы на самом деле делаете в SAS с этими данными после его чтения? Если вы просто делаете это, SAS - это плохой инструмент для этой цели (perl будет лучше, python, что угодно). Если вы делаете что-то более сложное, скорее всего, есть лучшие способы сделать это, если вы объясните, что вы делаете. – Joe

+0

Конечно, вы можете использовать мой подход с этим набором макросов. В принципе, если набор данных idcodes содержит ВСЕ идентификационные коды всех нужных вам тикеров, остальные из них будут работать нормально. Затем, когда вы делаете экспорт, вы просто меняете экспорт с помощью 'proc export' на запись на этапе ввода данных (как я писал в своем ответе), используя параметр' filevar' и имя тикера в переменной имени файла. dlm = '09'x, если вы хотите разграничить табуляцию. – Joe

+1

Просто помните, что вы написали:% do iter = 1 to & OBSCOUNT; Вы также должны иметь процент перед этим:% do iter = 1% to & OBSCOUNT; – mvherweg

ответ

0

Это в основном другой ответ, поэтому поставим его здесь. Вот как я подходил к второй части - никаких макросов вообще. Я предполагаю, что их ежегодные наборы данных отсортированы уже сексидом; если нет, это может быть немного сложнее, просто чтобы избежать слияния.

proc sql; 
select quote(ticker) into :tickerlist separated by ',' from companies; 
quit; 

data idcodes; *you could also create this by merging optiomn.secnmd to companies by ticker.; 
set optionm.secnmd; 
where lowcase(ticker) in (&tickers.); 
run; 

proc sort data=idcodes nodupkey; 
by secid; 
run; 

proc print data=idcodes; 
run; 

data lotsofyears/view=lotsofyears; 
set 
optionm.vsurfd2010 
optionm.vsurfd2011 
optionm.vsurfd2012 
optionm.vsurfd2013 
; *or however many you need, you could generate this list if it is long; 
by secid; 
run; 

data mydata; 
merge lotsofyears(in=a) idcodes(in=b); 
by secid; 
filenm=cats("c:\mydir\mydata_",ticker,".dat"); *or secid if that is better; 
run; 
proc sort data=mydata; 
by ticker; 
run; 
data _null_; 
set mydata; 
file a filevar=filenm dlm='09'x lrecl=32767; 
put (_all_)($); *or perhaps a more complex put statement - see what proc export generates; 
run; 
+0

Спасибо за ваш полный и полный ответ, вы очень помогаете. Есть некоторые части кода, которые я не понимаю полностью, не могли бы вы мне помочь? А именно: Строка 3: где низкий регистр (тикер) в (& тикеры.); тикерами должен быть список тикеров, но как его создать? Через proc sql, как вы в своем ответе выше? Линия 12: данные lotsofyears/view = lotsofyears; Я видел этот тип использования, но я его не понимаю. Что означает слэш (/) в этом контексте? Кроме того, я прочитаю об объединении данных, потому что пока не понимаю. – sasstudent

+0

А, я оставил создание этого - это было в моем предыдущем ответе, да, я добавлю его обратно. Представление создает представление набора данных - например, представление sql, оно фактически не выполняется через данные , он просто запоминает, как вы хотите использовать данные для последующего использования. Вот как вы его создаете - 'данные /view '. «MERGE» - это эквивалент соединения SAS, в основном. – Joe

+0

Спасибо за ваш ответ. Я до сих пор не получаю что-то, и я не могу заставить его работать. Я опубликую мои вопросы как можно скорее. – sasstudent

1

Вы должны предшествовать макропеременную по &, так firstobs=&iter..

Однако я не уверен, что вы действительно хотите это сделать. Почти все, что вы, возможно, захотите сделать, макро-итерацией по набору данных, которую вы можете сделать, путем регулярного повтора по набору данных и, возможно, с использованием групп BY. Макро итерация очень неэффективна по сравнению с использованием встроенных методов SAS.

Чтобы вызвать набор кодов для каждой строки в наборе данных, вы должны сделать что-то вроде этого.

%macro pulldata(ticker); 
data stock_data; 
set big_database; 
where ticker="&ticker"; 
file "c:\mydir\myfile_&ticker..csv" dlm=',' lrecl=32767; *double period - first is macro variable delimiter; 
put (_all_) ($); 
run; 
%mend pulldata; 

data _null_; 
set companies; 
call execute('%pulldata(',ticker,')'); 
run; 

Вы также можете сделать что-то вроде этого, где мы используем опцию filevar, чтобы позволить набор данных высовываться в несколько файлов (должны быть отсортированы по filevar!)

proc sql; 
select quote(ticker) into :tickerlist separated by ',' from companies; 
quit; 

data mydata; 
set bigdata; 
where ticker in (&tickerlist.); 
filen = cats('c:\mydata\myfile_',ticker,'.csv'); 
run; 

proc sort data=mydata; 
by filen; 
run; 

data _null_; 
set mydata; 
file a filevar=filen dlm=',' lrecl=32767; 
put (_all_) ($); 
run; 
+0

Благодарим вас за ответ. Я обращаюсь к WRDS, исследовательскому сервису, который объединяет несколько академических баз данных, и они сами предлагают использовать SAS. Вместо использования веб-интерфейса, который не позволяет мне выполнять запросы пакетных данных, я пытаюсь использовать SAS для автоматизации необходимого извлечения данных. Итак, идея заключается в получении списка акций, для которых я хочу извлечь данные, а затем просить об этом, один за другим (мне нужны отдельные файлы). Я успешно использовал образец SAS для одного запаса, и он выполняется довольно быстро, поэтому для меня это кажется хорошей альтернативой. – sasstudent

+0

А, ок. Так что вы, вероятно, захотите сделать, это создать набор данных со всеми необходимыми файлами, а затем, какой бы ваш код не извлек файл из WRDS, поместите его в макрос, используя такие параметры, как «имя запаса» или что-то еще. Затем используйте CALL EXECUTE для вызова этого макроса. Я отредактирую краткое объяснение в ответе. – Joe

+0

(продолжение) Основная идея: получение списка тикеров, а затем выполнение некоторых макрокоманд (еще не закодированных) для каждого из них для извлечения необходимых мне данных - это, по существу, открытие .sas-файлов, выполнение proc sql для ограничения данных к тому, что мне нужно, и вывод в файл .csv. – sasstudent

Смежные вопросы