SAS filevar с несколькими переменными и значением fileref

Недавно я узнал об операторе filevar. Можно ли использовать это для записи различных текстовых файлов, разделенных несколькими переменными? Все примеры, которые я видел в Интернете, записывались в текстовые файлы только на основе одной переменной, на которую они хотят разделить.

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

Могу ли я затем использовать filevar для записи нескольких текстовых файлов, разделенных всеми этими переменными одновременно (возможно, путем объединения их в пути к файлу, а затем установить этот путь к файлу как ссылку на файл)? Итак, я бы получил один текстовый файл, в котором make = A, цвет = красный, год = 2000. Второй текстовый файл с параметрами make=A, color=Blue, year=2000 и т. д.

Также я продолжаю видеть слово fileref, но нет четкого объяснения того, что есть на самом деле. Интуитивно я чувствую, что это просто псевдоним имени файла, на который мы можем ссылаться в коде?

Спасибо.


person VBACODER    schedule 20.07.2017    source источник


Ответы (3)


Вы можете думать о fileref как об указателе на файл, как в C/C++.

Вы абсолютно можете управлять выводом файла, используя значения из набора данных. Вот пример использования первых нескольких наблюдений из данных SASHELP.CARS.

proc sort data=sashelp.cars (where=(make in ('Acura', 'Audi', 'BMW')))
          out=cars;
by make type;
run;

data _null_;
set cars;
by make type;
retain fid;
if first.type then do;
    f_name = catt("c:\temp\",make,"_",type,".txt");
    rc = filename("temp",f_name);
    fid= fopen("temp","o");
    rc = fput(fid,'make,model,type,msrp');
    rc = fappend(fid);
end;

rc = fput(fid,catx(",",make,model,type,msrp));
rc = fappend(fid);

if last.type then do;
    rc = fclose(fid);
end;
run;

Это создает файл CSV для каждой группы MAKE, TYPE, в котором указано название автомобиля и рекомендованная производителем розничная цена.

Для каждой группы:

  1. f_name — это имя физического файла для вывода. функции filename() и fopen() открывают файл для вывода. fid — это ссылка на файл.
  2. fput() помещает строку в буфер.
  3. fappend() добавляет буфер к файлу. Сделайте это для заголовка, а затем один раз для каждой записи.
  4. в конце группы закройте файл с помощью fclose()
person DomPazz    schedule 20.07.2017
comment
Спасибо за ответ. Я могу проследить это до строки f_name и потом не понять, что происходит. (Является ли fid скрытой переменной, которую использует SAS?). В rc=filename(...) есть временная ссылка на ваш файл? Что представляет собой второй параметр в имени файла (документация SAS, которую я не нашел очень полезной). Извиняюсь за все вопросы, новичок в этом типе SAS. - person VBACODER; 20.07.2017
comment
fid — переменная-указатель. Я добавлю немного больше к ответу. - person DomPazz; 20.07.2017
comment
Это хороший пример, но кажется, что это излишество, не так ли (поскольку вы можете использовать filevar для этого с обычным файловым вводом-выводом)? - person Joe; 20.07.2017
comment
Спасибо! Является ли fid произвольным именем или SAS всегда использует это имя? После поиска в Google я наткнулся на f_id, поэтому я предполагаю, что это просто произвольное имя указателя? - person VBACODER; 20.07.2017

Ты совершенно прав; вы можете использовать filevar для определения имени файла на основе данных в вашем наборе данных.

Вот простой пример использования sashelp.cars для создания набора файлов, по одному для каждой марки автомобиля.

filename a temp;
data _null_;
  set sashelp.cars;
  outname = cats('c:\temp\',make,'.txt');
  file a filevar=outname dlm=',';
  put make $ model $ mpg_city mpg_highway;
run;

Имя файла a — это ненужное имя файла, потому что оно должно иметь что-то в этом месте синтаксиса. Он ничего не делает (отсюда и temp).

Обратите внимание: используя этот метод, вы должны правильно отсортировать файл (в группах, соответствующих вашим файлам). В противном случае он не будет работать так, как вы хотите. Он не обязательно должен быть упорядочен по этой переменной, но должен быть упорядочен по этой переменной. Так что это нормально:

A
A
B
B
G
G
C
C
D
D

Но не это:

A
B
G
C
D
A
B
G
C
D

Вы также должны убедиться, что у вас есть допустимые имена файлов (поэтому не используйте model в sashelp.cars, если только вы не очистите его, так как в нем много недопустимых символов, таких как \).

person Joe    schedule 20.07.2017
comment
Спасибо за ответ! Могу ли я расширить это так, чтобы это было, скажем, outname= Cats('c:\temp\',make,color,prodyear'.txt'); для того, чтобы разделить файлы на цвет марки и год выпуска в одном файле. А затем перебрать все возможные комбинации? Никогда раньше не приходилось использовать файлы в SAS, а я довольно начинающий программист. Извиняюсь за глупые вопросы. - person VBACODER; 20.07.2017
comment
Конечно, вы могли бы (конечно, вы получили бы много файлов). Вам не нужно зацикливаться, шаг данных сделает это за вас. Пока outname становится допустимым именем файла, а данные организованы таким образом, что любой набор записей, который вы хотите вывести в один файл, группируется перед его выводом, все в порядке. - person Joe; 20.07.2017
comment
Данные не нужно группировать заранее. SAS просто открывает и закрывает файл по мере изменения сгенерированного имени файла. - person Tom; 20.07.2017
comment
@Tom Хотя SAS с радостью сделает это, он не будет добавлен; сравните мой пример с идентичным, за исключением АВТОМОБИЛЕЙ, отсортированных по модели (изменение ввода). Затем Acura, например, имеет 2 ряда вместо 7 (поскольку в последнем упоминании Acura 2 ряда подряд). - person Joe; 20.07.2017
comment
Я использовал оператор FILE для записи в несколько файлов, когда данные не сортируются много раз. Вероятно, вам нужно включить опцию MOD. - person Tom; 21.07.2017

Я думаю, вы говорите об опции FILEVAR= в выражении FILE. Это говорит SAS использовать значение определенной переменной, чтобы найти имя файла для записи. Вы можете построить его из чего угодно.

fileref — это псевдоним, который вы создаете, когда используете оператор FILENAME или функцию FILENAME(). Так же, как libref — это псевдоним, который вы создаете, когда используете оператор LIBNAME или функцию LIBNAME().

Таким образом, вы можете определить ссылку на файл, которая указывает на один или несколько файлов.

filename file1 '/project1/source.csv';
filename file2 ('/project1/source1.txt' '/project1/source2.txt');

И затем вы можете использовать ссылку на файл в местах, где вы, возможно, ранее использовали физическое имя файла в кавычках.

infile file1 dsd ;
infile file2 eov=eov ;

Вы также можете использовать fileref для указания каталогов.

filename raw '/project1/' ;

А затем добавьте () для ссылки на определенные файлы в этих каталогах.

infile raw('source.csv') dsd ;
infile raw('source1.txt' 'source2.txt') eov=eov;
file raw('export.csv') dsd ;
person Tom    schedule 20.07.2017