2017-06-26 2 views
1

Dieser Codeabschnitt wird nicht ordnungsgemäß ausgeführt, wenn in jeder Liste mehr als eine Sache vorhanden ist.So korrigieren Sie den SAS-Fehler über Positionsparameter Makrovariablen

%macro loop(list1, list2); 

    %let n=%sysfunc(countw(&list1)); 
    %do i=1 %to &n; 
    %let O_list1 = %scan(&list1, &i, ''); 
    %let O_list2 = %scan(&list2, &i, ''); 

data taxes; 
    food=3*&O_List1; 
    materials = 4*&O_List2 

%end; 
%mend; 

%loop(1, 4); 
/* %loop(1 3, 4 6) */ 

Hier ist der Ausgang 3 und 16. Wenn ich die Schleife machen, wie es in dem kommentierten Abschnitt ist der Code nicht läuft und ich kann nicht, warum scheinen, um herauszufinden. Vielen Dank!

+0

Nicht auf Ihre Fehler im Zusammenhang, aber es ist eine gute Idee, eine 'läuft hinzuzufügen;' Anweisung Ihren DATA Schritt zu beenden. – Quentin

+0

Da Sie% SCAN() angewiesen haben, dass Ihre Listen durch einfache Anführungszeichen getrennt sind, enthält Ihr Beispiel nur EINEN Eintrag in jeder Liste. Dies bedeutet, dass der in dieses Element eingebettete Speicherbereich dazu führt, dass Ihr Makro ungültigen SAS-Code generiert. Auch die Gesamtlogik des Makros ist fehlerhaft, da es immer dasselbe Ausgabe-Dataset überschreibt, wenn mehrere Elemente in der Liste vorhanden sind. Was ist das Gesamtziel des Makros? – Tom

+0

@Tom Danke, dass ich darauf hingewiesen habe. Ich habe a_ & I hinzugefügt, um das Überschreibungsproblem zu beheben. Das Ziel des Programms in meinem realen Programm ist es, über zwei Listen gleichzeitig zu iterieren. Auf diese Weise kann ich einen Tisch bekommen, den ich brauche. Jetzt, da ich das herausgefunden habe, muss ich herausfinden, wie man alle erstellten Tabellen anfügt. –

Antwort

2

Versuchen Sie, das dritte Argument in %scan von '' zu %str() zu ändern. Im Moment suchen Sie nach einem ' Trennzeichen in Ihren Eingabelisten, da in der SAS Makrosprache alles Text ist und Sie keine Zeichenkonstanten wie in Procs und Datenschritten angeben müssen. Sie können jedoch nicht einfach einen nicht angezo- genen Platz eingeben, da der Makroprozessor alles abschneidet. Sie müssen also eine der entsprechenden Makro-Quotierungsfunktionen verwenden.

Sie können auch in der Dokumentation für Arrays in SAS nachsehen, da dies normalerweise die einfachere Möglichkeit ist, Berechnungen mehrmals innerhalb eines Datenschritts auszuführen.

+0

Danke das hat geholfen! Ich fügte auch ein Semikolon hinzu, das auf den Linien fehlt, in denen die variablen Materialien erklärt werden. Die run-Anweisung wurde auch nach% mend hinzugefügt. Ich frage mich nur, würde die Option Arrays in der Laufzeit dafür schneller sein? Vielen Dank! –

0

Stellen Sie sicher, dass für die Funktionsaufrufe COUNTW() und% SCAN() dasselbe Trennzeichen verwendet wird. Denken Sie daran, dass Anführungszeichen für den Makroprozessor Teil der Strings sind und dass ein Leerzeichen am Anfang oder Ende des Werts enthalten sein muss, um ein Makro zu zitieren.

%let n=%sysfunc(countw(&list1,%str())); 
%do i=1 %to &n; 
    %let item1 = %scan(&list1, &i, %str()); 
    %let item2 = %scan(&list2, &i, %str()); 

Wenn Ihre Listen sind wirklich nur einen Datensatz mit & N Beobachtungen erstellen verwendet werden, dann haben Sie wahrscheinlich nicht brauchen% DO oder% SCAN() zu verwenden.

%macro taxes(list1, list2); 
%local n ; 
%let n=%sysfunc(countw(&list1)); 

data taxes; 
    array _1 (&n) _temporary_ (&list1); 
    array _2 (&n) _temporary_ (&list2); 
    do row=1 to &n ; 
    food=3*_1(row); 
    materials = 4*_2(row); 
    output; 
    end; 
run; 

%mend; 
%taxes(list1=1 3, list2=4 6); 
proc print data=taxes; 
run; 

enter image description here

Verwandte Themen