2011-04-29 4 views
2

데이터 단계를 거치는 동안 특정 값의 데이터 집합을 포함하는 문자열 변수를 만드는 방법을 찾고 있습니다. OneTwoFour (또는 더 나은 FourTwoOne) : 데이터 단계를 통한 SAS 변수 연결

AddToStringYN Value 
    Y   One 
    Y   Two 
    N   Three 
    Y   Four 
    N   Five 

그래서 결국, 변수가 같을 것이다

예 데이터 work.test을 설정합니다. 이것은 매우 단순 해 보입니다.하지만이를 수행 할 방법을 찾지 못하는 것 같습니다. 나는 또한이 같은 매크로 변수와 함께 작동하도록 시도 :

%let stringvar=; 
Data _null_; 
    set work.test; 
    if AddToStringYN = "Y" then do; 
    call symput('stringvar',"&stringvar" || strip(value)); 
    end; 
Run; 

을하지만이 제공 :

GLOBAL STRINGVAR Four 

그래서 내가 마지막 값을 가져옵니다. 나는 이것이이 매크로 기능에 대한 나의 오해 때문에야만한다는 것을 알았지 만 왜 변수에 마지막 값만있는 지 이해할 수 없다. 나는 단지 그것을 실제로 실행 또는 뭔가했다는 symput라는 마지막 시간이었다 생각하지만 난에 코드를 조정 한 후 :

GLOBAL STRINGVARONE One 
GLOBAL STRINGVARTWO Two 
GLOBAL STRINGVARFOUR Four 
: 다음

%let stringvar=; 
Data _null_; 
    set work.test; 
    if AddToStringYN = "Y" then do; 
    call symput('stringvar'||strip(value),"&stringvar" || strip(value)); 
    end; 
Run; 

나는 그들 모두를받을 수 있나요

내 마지막 추측은 데이터 단계를 거치는 것인데, 'call symput ...'행은 실제로 "& stringvar"가 대체 된 매크로 프로세서에 추가되고 마지막 명령문이 모두 실행 된 후에 만 ​​추가됩니다.
이것은 좋은 가정입니까 아니면 다른 설명입니까? 원래의 질문으로 돌아가서 : 이것을 달성하는 쉬운 방법이 있습니까 (원하는 변수가 있습니까)? 간단한데

답변

2

안녕하세요, 여기 내 솔루션입니다 :

data a; 
set test end=eof; 
length cat $100.; 
retain cat; 
if AddToStringYN = "Y" then do; 
    cat=trim(left(cat))||trim(left(value)); 
end; 
if eof then do; 
    call symput("VAR",cat); 
    output; 
end; 
run; 

%put VAR=&VAR; 

당신이 열 "CAT"의 데이터 세트에 변수의 연결이이 예에서 당신은 macrovariable VAR와이 같은 목록

+0

완전한! 나는 이와 같은 몇 가지 구조 (retain과 sas 변수 재사용의 조합)를 사용하려고 시도했으나 작동하지 않았다. 아직 다른 것을 찾을 수는 없지만 IT가 작동합니다! 그리고 실제로는 충분히 간단합니다 .... 어디를 봐야할지 안다면) 고마워요! (내 논리가 매크로 변수에 맞으면 추가 질문에 대한 생각은 없습니까?) – Yoh

+1

또한 trim (left()) 함수를 cat(), catt(), cats(), catx() 함수로 대체 해보십시오 . 그들은 매우 유연하고, 사용하기 쉽고, 자동 형 변환을 수행합니다! SAS9 이후부터 사용 가능합니다 ... –

+0

@Rob 스트립()을 사용하고 있습니다. – Yoh

5

다음은 내 대답은 your identical question on RunSubmit.com입니다. 나는 당신과 @Fabio가 솔루션을 과도하게 설계 할 수 있다고 생각합니다. 데이터 단계 코드를 반복적으로 작성할 필요가 없습니다. ...

먼저, 수행하려는 작업을 수행하는 쉬운 방법은 다음과 같습니다 : 여기

proc sql; 
    select Value into :StringVar separated by '' 
    from work.test 
    where AddToStringYN='Y' 
    ; 
quit; 

, 당신은 select into 구문을 사용하여, SAS/MACRO와 SQL 인터페이스를 활용할 수 있습니다. 당신은 심지어 당신이 찾고있는 특정 주문을 얻기 위해 order by 절을 추가 할 수 있습니다.

둘째, SAS 매크로가 작동하는 방식에 대해 뭔가 알고 있었기 때문에 처음 예제에서 컴파일러가 코드를 실행하기 전에 수행하는 작업은 &stringvar 값을 확인하는 것입니다. , 그 시점에서 비어 있습니다. 컴파일 후이 토큰이 바뀌면 코드는 SAS에 다음과 같이 나타납니다.

%let stringvar=; 
Data _null_; 
    set work.test; 
    if AddToStringYN = "Y" then do; 
    call symput('stringvar',"" || strip(value)); 
    end; 
Run; 

...SAS는 계속 진행하여 해당 코드를 실행합니다 (유효한 코드 일 수 있지만 빈 문자열을 연결하여 시작합니다). 그리고 데이터 단계가 작동하는 방식 때문에 데이터 단계의 각 반복은 사실 StringVar의 값을 대체합니다. 따라서 데이터 단계의 끝에서 마지막으로 읽은 값이 남았습니다.

+0

RunSubmit에 대한 답변을 봤습니다. 아직 답변을 드릴 시간이 없었습니다. 특히 많은 것에 대해 감사드립니다. SAS 매크로. 사실, 나는 그것이 작동하는 방식을 너무 많이 생각하고 있었고, macrovariable의 해결은 데이터 단계의 모든 반복이 아니라 한 번만 발생했습니다. proc sql 사용에 관해서 : 저는 항상 SQL보다 SAS 코드 우선 순위 (즉, 처리 시간)를 사용하는 방법을 배웠습니다. 비록 이것이이보기를 위해 꼭 잡는 지 나는 모른다. – Yoh

+1

@Yohsoog : SAS 데이터 스텝 코드 대 PROC SQL의 성능에 대한 엄격한 규칙은 없습니다. 어느 것이 빠르면 모든 요인에 달려 있습니다. 2 가지 솔루션을 시도해보고 로그를 확인하여이 경우 데이터가 가장 빠른 것을 확인할 수 있습니다. 하지만 코드에 대한 가독성, 유지 보수성, 타인에 대한 명확성, 코딩 표준 등과 같은 다른 고려 사항이 있습니다. 나 또한 PROC SQL 메서드를 사용하는 경향이 있습니다. 그 결과에 대해 I/O를 가치있게 만드는 데이터 단계. – sasfrog

+0

예, 실제로이 경우 데이터 단계에서 다른 많은 작업을 수행하고 있습니다. 데이터 단계는 실제로 전체 XML을 생성하는 표를 통해 반복됩니다. 그리고 여기에 집어 넣은 문자열은 동일한 데이터 단계에서 다른 곳에서도 잘려서 PROC SQL 메서드를 사용하는 것은 실제로 불가능합니다. 하지만 가독성 등을 고려하여 고려해 보는 것이 좋습니다. – Yoh