2015-07-01 3 views
1

У меня есть большая таблица SAS, давайте опишем колонки как столбцы A и B в символьном формате, а все остальные столбцы будут отображаться в цифровом формате (каждая переменная имеет другое имя) с неизвестной длиной N, например:Привести длину массива к другому массиву в SAS?

A  B Name1 Name2 Name3 .... NameN 
------------------------------------------------- 
Char Char Number1 Number2 Number3 ..... NumberN 
................................................. 
................................................. 

цель состоит в том, что численный массив Name1-Намюр подведут вниз через класс = в (к в), Так что финальный стол будет выглядеть следующим образом:

A  B Name1 Name2 Name3 .... NameN 
---------------------------------------- 
Char Char Sum1 Sum2 Sum3 ..... SumN 
........................................ 
........................................ 

Для этого sum- Я описал 2 массива. Первый:

array Varr {*} _numeric_; /* it reads only numerical columns */ 

Затем я описал другой массив с теми же длинами (Summ1-SummN), чтобы сделать процесс суммы вверх.

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

array summ {80} Summ1-Summ80; 

код работает, когда я пишу это вручную. Но вместо этого я хочу написать что-то вроде

array summ {&N} Summ1-Summ&N; /* &N is the dimension of the array Varr */ 

Я попытался с сделай петлю и тусклой (Варра) в массиве по-разному, как:

data want; 
array Varr {*} _numeric_; 
do i=1 to dim(Varr); 
    N+1 ; 
end; 
%put &N; 
array Summ {&N} Summ1-Summ&N; 
retain Summ; 

if first.B then do i=1 to dim(varr); summ(i)=varr(i) ;end; 
else do i =1 to dim(varr); summ(i) = summ(i) + varr(i) ; varr(i)=summ(i); end; 

drop Summ1-Summ&N; 
run; 

Но это не работает. Любая идея о том, как перенести длину первого массива во второй массив?

+0

Хм, если я правильно понимаю вашу проблему, N - переменная datastep, & N вызывает макрокоманду, поэтому вы должны использовать call symput ('N', N); после цикла или лучше: call symput ('varrLen', dim (Varr)); и удалить цикл (не уверен, что n зарезервировано из глобальной макропеременной) – kl78

+0

Теперь я попытался с обоих после цикла с вызовом symput ('N', N); и внутри цикла с вызовом symput ('varrLen', dim (Varr)); Оба указали ту же ошибку для следующего кода: массив Summ {*} Summ1-Summ & N; Ошибка: «Отсутствует числовой суффикс в списке нумерованных переменных (Summ1-SummN)». – user3714330

+0

Я думаю, вы должны использовать summ "& N", но я не уверен, что вы можете сгенерировать имя переменной таким образом. Лучше попробуйте решение Keiths сперва – kl78

ответ

2

Вам нужно вычислить и сохранить число числовых переменных на предыдущем шаге. Самый простой способ - использовать таблицу метаданных dictionary.columns, доступную в proc sql. Это содержит все данные столбца для данного набора данных, включая тип (num или char), поэтому вам просто нужно подсчитать количество столбцов, где тип «num».

Код ниже делает именно это и сохраняет результат в макропеременной & N., используя функциональность into :. Я также использовал функций left и put, чтобы удалить начальные пробелы из макропеременной, в противном случае вы будете сталкиваться с проблемами при вводе summ1-summ&N.

Я также добавил 2-ое решение, основанное на ваш ответ, но будет более эффективным так как он не читал ни в каких отчетах, только детали колонки

proc sql noprint; 
select left(put(count(*),best12.)) into :N 
from dictionary.columns 
where libname='SASHELP' and memname='CLASS' and type='num'; 
quit; 

%put Numeric variables = &N.; 

/*****************************************/ 
/* alternative solution */ 

data _null_; 
set sashelp.class (obs=0); 
array temp{*} _numeric_; 
call symputx('N',dim(temp)); 
run; 

%put Numeric variables = &N.; 
+0

Я использовал ваш код 'proc sql' сразу после основной таблицы, но он дает' N = 3' вместо 'N = 87' (это должно быть 87). Я рассматриваю, если я написал какой-либо параметр неправильно. Я проверил свойства таблицы: 'type = 'Number'', поэтому я сделал это. Я также задаюсь вопросом о 'memname', это мое имя таблицы? (в этом случае это временная таблица, сохраненная в библиотеке 'work') – user3714330

+0

@ user3714330 В качестве примера я использовал набор данных' sashelp.class'. Вам нужно изменить 'libname' и' memname' на любую библиотеку и набор данных, которые вы используете – Longfish

+0

Да, теперь это работает, спасибо ... – user3714330

1

Теперь я нашел другое решение с небольшой модификацией раствора от @ kl78

Раньше, когда я попытался с call symput ('N',dim(varr)); я забыл изменить числовой формат и удаление unec промежуточные пространства. Когда я запускаю его без форматирования, код пытался найти Summ_____87, поэтому он дал ошибку.

Теперь я запускаю его с форматом, call symput ('N',put(dim(varr),2.)); код может найти Summ87, так что теперь он полностью справляется.

+1

'call symputx' также обрезает пробелы, без необходимости' put' (который в вашем случае работает только в том случае, если число переменных составляет от 10 до 99). – Longfish

+0

Я добавил второе решение к моему ответу в соответствии с вашими соображениями, но сделал более эффективным, не прочитав в записях данных – Longfish

+0

Да, это работает красиво. Теперь я узнал новую команду. – user3714330

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