tipps und tricks - universitaetsrechenzentrum · tipps und tricks für den leichteren umgang mit...
TRANSCRIPT
Tipps und Tricksfür den leichteren Umgang
mit der SAS Software
Sabine Erbslöh und Christina Gelhorn
Statistical Programming, Accovion GmbH
15. KSFE-Tagung, Heidelberg, 24. Februar 2011
2
Inhalt I
Problem aus der Statistik: Konfidenzintervalle für 0%
Feinheiten zu PROC Report
• Erstellen von horizontalen Linien in RTF-Tabellen
• Seitenumbruch nach einer Spalte
Arbeiten mit Datumsfeldern
• Auffüllen unvollständiger Datumsangaben
• Umwandeln von Datum und Zeit in Datetime
Achtung – Was geht nicht in SAS
• LAG-Funktion in einer IF/ELSE-Anweisung
• Vorsicht mit weiteren Anweisungen nach Merge
• Ab SAS 9.2 Abfrage mit IN auch in der Makro-Sprache
3
Inhalt II
Einfach bequem
• Anzeigen von Variablennamen UND Variablenlabels
• Angriff der SAS Kloneditoren unter Windows
Kurz und elegant
• Verschiedene DO Schleifen
• Möglichkeiten des SELECT Statement
• CALL MISSING
Nützliche Funktionen
• SMALLEST und LARGEST
• STRIP, COMPBL, SUBSTRN
4
Konfidenzintervalle für 0% mit PROC FREQ
Untersucht wird die Wahrscheinlichkeit des Auftretens einer allergischen Reaktion auf das Medikament
Die Reaktion wurde bei keinem der Patienten beobachtet
Beispieldatensatz:
21010
299
8
7
6
5
4
3
2
1
obs
28
27
26
25
24
23
22
21
1=allergische Reaktion, 2=keine allergische ReaktionPatient
5
Konfidenzintervalle für 0% mit PROC FREQ
proc freq data = status;
table ereignis / binomial;
run;
1.0000 95% Upper Conf Limit
0.691595% Lower Conf Limit
Exact Conf Limits
1.000095% Upper Conf Limit
1.0000 95% Lower Conf Limit
0.0000 ASE
1.0000Proportion
Binomial Proportion for EREIGNIS = 2
6
Konfidenzintervalle für 0% mit PROC FREQ
PROC FREQ liefert im Normalfall nur Schätzer für die Eintrittswahrscheinlichkeit des Ereignisses „keine allergische Reaktion“.
Das Konfidenzintervall für die Eintrittswahrscheinlichkeit des Ereignisses „allergische Reaktion“ lässt sich mit PROC FREQ nur über Umwege berechnen
proc format;
value statusf
1 = "allergische Reaktion"
2 = "keine allergische Reaktion";
run;
1. Definition eines Formats, das alle möglichen Ausprägungen der Variablen enthält:
7
Konfidenzintervalle für 0% mit PROC FREQ
2. Auszählung der absoluten Häufigkeit aller so festgelegten Kategorien mit PROC TABULATE
10
NN
keine allergische Reaktionallergische Reaktion
1=allergische Reaktion, 2=keine allergische Reaktion
proc tabulate data = status out = anz;
class ereignis / preloadfmt;
table ereignis * n / printmiss;
format ereignis statusf.;
run;
8
Konfidenzintervalle für 0% mit PROC FREQ
3. Missings werden durch Nullen ersetzt.
data anz;
set anz;
if n eq . then n = 0;
run;
4. Ergebnis wird PROC FREQ unter Verwendungdes WEIGHT Statements übergeben.
• Gewichte: Anzahl der Beobachtungen in denjeweiligen Kategorien
• Damit dabei die Null berücksichtigt wird, muss zusätzlich die Option ZEROS angegeben werden
9
Konfidenzintervalle für 0% mit PROC FREQ
proc freq data = anz;
weight n / zeros ;
table ereignis / binomial;
run;
0.3085 95% Upper Conf Limit
0.000095% Lower Conf Limit
Exact Conf Limits
0.000095% Upper Conf Limit
0.0000 95% Lower Conf Limit
0.0000 ASE
0.0000Proportion
Binomial Proportion for EREIGNIS = allergische Reaktion
10
Feinheiten zu PROC REPORT
Erstellen von horizontalen Linien in RTF-Tabellen
Seitenumbruch nach einer Spalte
11
PROC REPORT - horizontale Linien in RTF-Tabellen
Vertikale Linien werden „automatisch“ erzeugt
Um horizontale Linien zu erhalten, muss man mit styles, brdrt, brdrs und brdw arbeiten
Beispieldatensatz:
8
7
6
5
4
3
2
1
obs
Severe NauseaGastrointestinal disorders789
Severe NauseaGastrointestinal disorders456
GlaucomaEye disorders456
ConjunctivitisEye disorders456
BlindEye disorders456
Severe NauseaGastrointestinal disorders123
GlaucomaEye disorders123
ConjunctivitisEye disorders123
Adverse Event TermSystem Organ ClassPat.ID
12
PROC REPORT - horizontale Linien in RTF-Tabellen
1. Erzeugen eines regulären lst-output
System Organ Class Adverse Event Term Pat.ID __________________________________________________________ Eye disorders Blind 456 Conjunctivitis 123 456 Glaucoma 123 456 Gastrointestinal disorders Severe Nausea 123 456 789
PROC REPORT data=test nowindows spacing=3
headline headskip;
column soc event subjid ;
define soc / order width=30 flow;
define event / order width=20 flow;
define subjid / width=10;
RUN;
13
PROC REPORT - horizontale Linien in RTF-Tabellen
2. Erzeugen eines RTF output ohne weitere Angaben PROC REPORT data=test nowindows
style={rules=cols cellspacing=0 cellpadding=0};
column soc event subjid ;
define soc / order width=30 flow;
define event / order width=20 flow;
define subjid / width=10;
RUN;
789456disorders123Severe NauseaGastrointestinal456123Glaucoma456123Conjunctivitis456BlindEye disordersPat.IDAdverse Event TermSystem Organ Class
14
PROC REPORT - horizontale Linien in RTF-Tabellen
Definition von horizontalen Linien basiert aufRTF Spezifikationen
Sie werden innerhalb eines compute statement alscall define definiert
Einstellungen für die Absatzränder:
• brdrt: Border top
• brdrs: Single-thickness border
• brdwN: Border width N (in twips)N = Breite des Stiftes für den Rahmen
15
PROC REPORT - horizontale Linien in RTF-Tabellen
3. Erzeugen des RTF output mit horizontalen Linien
PROC REPORT data=test nowindows spacing=3 headline headskip
style={rules=cols cellspacing=0 cellpadding=0}
style(header column)=[protectspecialchars=off ];
column soc event subjid ;
define soc / order width=30 flow;
define event / order width=20 flow;
define subjid / width=10;
compute subjid;
if soc ne ' ' then call define
('_c1_','style','style=[pretext="\brdrt\brdrs\brdrw11"]');
if event ne ' ' then call define
('_c2_','style','style=[pretext="\brdrt\brdrs\brdrw11"]');
if subjid ne ' ' then call define
('_c3_','style','style=[pretext="\brdrt\brdrs\brdrw11"]');
endcomp;
RUN;
16
PROC REPORT - horizontale Linien in RTF-Tabellen
Achtung! In Word sieht man die Linien erst im Print Preview!
789
456
123Severe NauseaGastrointestinal disorders
456
123Glaucoma
456
123Conjunctivitis
456BlindEye disorders
Pat.IDAdverse Event TermSystem Organ Class
17
PROC REPORT - Seitenumbruch nach einer Spalte
Seitenumbruch häufig gewünscht vor Beginn einer neuen Ausprägung der Gruppierungsvariablen-> Seitenumbruch nach einer Reihe
Manchmal aber auch wünschenswert, nach einer bestimmten Spalte einen Seitenumbruch zu erzwingen
PROC REPORT bietet auch die Möglichkeit, im definestatement mit /page zu arbeiten
Der Beispieldatensatz wurde um 3 Variablen erweitert: pt (preferred term), serious und related.
18
PROC REPORT - Seitenumbruch nach einer Spalte
1. Mit automatischem Spaltenumbruch
PROC REPORT data=test3 nowindows spacing=3 headline;
column subjid soc pt event serious related ;
define subjid / id order width=10;
define soc / order width=30 flow;
define pt / order width=20 flow;
define event / width=20 flow;
define serious / width=7;
define related / width=7;
RUN;
19
PROC REPORT - Seitenumbruch nach einer Spalte
Der erzeugte output benötigt 2 Seiten, der automatische Umbruch erfolgt NACH der Variablen Event
Pat.ID System Organ Class Preferred Term Adverse Event Term
_________________________________________________________________
123 Eye disorders Conjunctivitis Conjunctivitis
Glaucoma Glaucoma
Gastrointestinal Nausea Severe Nauseadisorders
456 Eye disorders Blindness Blind
...
Serious Related
Pat.ID Flag Flag
_____________________________
123 0 1
0 0
0 1
456 1 0
...
20
PROC REPORT - Seitenumbruch nach einer Spalte
2. Mit definiertem Spaltenumbruch
PROC REPORT data=test3 nowindows spacing=3 headline;
column subjid soc pt event serious related ;
define subjid / id order width=10;
define soc / order width=20 flow;
define pt / order width=20 flow;
define event / width=20 flow page;
define serious / width=7;
define related / width=7;
RUN;
21
PROC REPORT - Seitenumbruch nach einer Spalte
Der erzeugte output benötigt ebenfalls 2 Seiten, der definierte Umbruch erfolgt VOR der Variablen Event
Pat.ID System Organ Class Preferred Term
________________________________________________________
123 Eye disorders Conjunctivitis
Glaucoma
Gastrointestinal Nausea
disorders
456 Eye disorders Blindness
...
Serious Related
Pat.ID Adverse Event Term Flag Flag
_____________________________________________________
123 Conjunctivitis 0 1
Glaucoma 0 0
Severe Nausea 0 1
456 Blind 1 0
...
22
Arbeiten mit Datumsfeldern
Auffüllen unvollständiger Datumsangaben
Umwandeln von einzelnen Datums- und Zeitvariablen in eine Datetime Variable
23
Auffüllen unvollständiger Datumsangaben
Auffüllen mit dem letzten Tag des Monats
31
30
29
28
Wert
Januar, März, Mai, Juli, August, Oktober, Dezember
April, Juni, September, November
Februar mit Schaltjahr
Februar ohne Schaltjahr
Monat
Statt umständlicher Zuweisungen kann man vom ersten Tag des Folgemonats 1 Tag abziehen -> Makro
Voraussetzung: Datensatz mit numerischer Monats-und Jahres-Variable
Folgende Werte sollen eingesetzt werden:
24
Auffüllen unvollständiger Datumsangaben
Makro zum Ersetzen des letzten Tages im Monat
%macro get_lmdt(month=,year=,outdt=);
*** if month is December ---> fill with 31 ***;
if &month eq 12 then
&outdt=input(compress("3112"||put(&year,z4.)),ddmmyy8.);
*** else ---> 01 of next month - 1 day ***;
else
&outdt=input(compress("01"||put(&month+1,z2.)
||put(&year,z4.)),ddmmyy8.)-1;
format &outdt date9.;
%mend get_lmdt;
25
Umwandeln in Datetime Variable
Statt Kombinationen von input und Konkatenierung: datetm= input(put(dat,date7.) || "," ||
put(tim,time5.),datetime.);
oder datetm= (dat*24*60*60)+ tim;
Funktion dhms – Syntax: dhms(date,hour,minute,second)
datetm= dhms(dat,0,0,tim);
Auch ideal um Zeitfenster abzufragen: timelow = dhms(end,-5,-30,endtim);
timeupp = dhms(end,5,30,endtim);
26
Achtung – Was geht nicht in SAS
LAG Funktion in einer IF/ELSE-Anweisung
Vorsicht mit weiteren Anweisungen nach Merge (übernommen von Hr. Elmar Dunkl, RPS Research Germany GmbH, Nürnberg)
Abfrage mit IN auch in der Makro-sprache (SAS 9.2)
27
Achtung – LAG Funktion in einer IF/ELSE Anweisung
Beispiel: Mehrere Studienphasen,
• Beginn der Phase notiert
• Enddatum ist zu berechnen
19JUN2009325
29MAY2009224
08MAY2009123
27MAY2009212
06MAY2009111
Start DatumPhasePatient IDObs
28
Achtung – LAG Funktion in einer IF/ELSE Anweisung
data phase_end;
attrib enddt format=date9. label = "End Datum";
set phase;
by patient descending phase startdt;
if first.patient then enddt = .;
else enddt = lag(startdt);
run;
29
Achtung – LAG Funktion in einer IF/ELSE Anweisung
Ergebnis:
19JUN2009325
06MAY200929MAY2009224
29MAY200908MAY2009123
27MAY2009212
06MAY2009111
End DatumStart DatumPhasePatient IDObs
30
Achtung – LAG Funktion in einer IF/ELSE Anweisung
29MAY200929MAY200908MAY2009125
06MAY200919JUN200929MAY2009224
27MAY200906MAY200919JUN2009323
27MAY200906MAY2009112
27MAY2009211
Lag (else)Lag (if)
Lag
(normal)
Start
DatumPhase
Patient
IDObs
31
Achtung – LAG Funktion in einer IF/ELSE Anweisung
data phase_end;
attrib enddt format=date9. label = "End Datum";
set phase;
by patient descending phase startdt;
lag_startdt = lag(startdt);
if first.patient then enddt = .;
else enddt = lag_startdt;
run;
32
Achtung – LAG Funktion in einer IF/ELSE Anweisung
Ergebnis:
19JUN2009325
19JUN200929MAY2009224
29MAY200908MAY2009123
27MAY2009212
27MAY200906MAY2009111
End DatumStart DatumPhasePatient IDObs
33
Vorsicht mit weiteren Anweisungen nach Merge
5Heidelberg
4Heidelberg
3Berlin
2Berlin
1Berlin
Patient IDZentrum
Beispiel: Zwei Datensätze mit einer gemeinsamen Variablen werden gemischt, dann wird zu einer nicht gemeinsamen Variablen eine 1 addiert.
599Heidelberg
499Heidelberg
329Berlin
229Berlin
129Berlin
Patient ID
Zentrum
NummerZentrum99Heidelberg
29Berlin
Zentrum
NummerZentrum
34
Vorsicht mit weiteren Anweisungen nach Merge
data zentpat;
merge zentinfo
patinfo;
by zent;
zentnum = zentnum + 1;
run;
35
Vorsicht mit weiteren Anweisungen nach Merge
5Heidelberg
4Heidelberg
3Berlin
2Berlin
1Berlin
Patient IDZentrum
Das Ergebnis hat vielleicht nicht jeder erwartet:
5101Heidelberg
4100Heidelberg
332Berlin
231Berlin
130Berlin
Patient ID
Zentrum
NummerZentrum99Heidelberg
29Berlin
Zentrum
NummerZentrum
36
Vorsicht mit weiteren Anweisungen nach Merge
5Heidelberg
4Heidelberg
3Berlin
2Berlin
1Berlin
Patient IDZentrum
Programmdatenvektor (PDV)
99Heidelberg
29Berlin
Zentrum
NummerZentrum
ZENT=Berlin PATIENT=1 ZENTNUM=29 FIRST.ZENT=1 LAST.ZENT=0 _ERROR_=0
ZENT=Berlin PATIENT=2 ZENTNUM=30 FIRST.ZENT=0 LAST.ZENT=0 _ERROR_=0
data zentpat;
merge zentinfo
patinfo;
by zent;
zentnum = zentnum + 1;
run;
_N_=1
_N_=2
ZENT=Berlin PATIENT=3 ZENTNUM=31 FIRST.ZENT=0 LAST.ZENT=1 _ERROR_=0_N_=3
37
Abfrage mit IN auch in der Makro-Sprache
Ab SAS 9.2 Abfrage mit IN auch in der Makro-Sprache möglich.
Im DATA step schon lange üblich
DATA subset;
SET sashelp.class;
*** ausgeschrieben ***;
IF name='Alice' or name='James'
or name='John' or name='Judy';
*** abgekürzt mit IN ***;
IF name in('Alice', 'James', 'John', 'Judy');
RUN;
38
Abfrage mit IN auch in der Makro-Sprache
Innerhalb der Makrosprache war es vor SAS 9.2nicht möglich, mit IN zu arbeiten.
Folgender Code ergab eine Fehlermeldung:
%MACRO usein(proc,ds);
%if %upcase(&proc) IN (MEANS,PRINT) %then %do;
proc &proc data=&ds;
run;
%end;
%MEND usein;
%usein(print,sashelp.class);
ERROR: Required operator not found in expression:
%upcase(&proc) IN (MEANS,PRINT)
ERROR: The macro USEIN will stop executing.
39
Abfrage mit IN auch in der Makro-Sprache
Auch unter SAS 9.2 gibt es eine Fehlermeldung,weil zunächst Optionen gesetzt werden müssen:
• MINOPERATOR:Erlaubt es, den IN Operator zu benutzen
• MINDELIMITER: zur Definition eines TrennzeichensStandard: Leerzeichen
options minoperator mindelimiter=',';
Im Beispiel wurde das Komma als Trennzeichendefiniert, wie auch in der DATA step Version
Danach funktioniert die Anwendung des INOperator im Makro
40
Einfach bequem
Anzeigen von Variablennamen UND Variablenlabels
Angriff der SAS Kloneditoren unter Windows
41
Anzeigen von Variablennamen UND Variablenlabels
PROC PRINT zeigt entweder die Variablennamenoder die –label
Mit Hilfe von PROC SQL wird eine Makrovariable generiert, die beide Informationen enthält
Dazu wird der Dictionary-Datensatz columns
verwendet, hier am Beispiel von sashelp.class, dem vorher Label zugewiesen wurden Obs name label
1 Name Vorname
2 Sex Geschlecht
3 Age Alter in Jahren
4 Height Größe in Inch
5 Weight Gewicht in Pound
42
Anzeigen von Variablennamen UND Variablenlabels
Alle ‚name‘ und ‚label‘ des ausgewählten Datensatzes werden in eine Makrovariable geschrieben, die später zum Ausdrucken verwendet wird
%let lib= work; %let memname= class;
PROC SQL noprint;
select trim(name) !! "= '" !! trim(label)
!! " (" !! trim(name) !! ")'"
as newlabel into :newlabel separated by " "
from dictionary.columns
where libname eq upcase("&lib") and
memname eq upcase("&memname.");
quit;
43
Anzeigen von Variablennamen UND Variablenlabels
PROC PRINT width= minimum data= &lib..&memname label;
label &newlabel. ;
run;
Name= 'Vorname (Name)' Sex= 'Geschlecht (Sex)' Age=
'Alter in Jahren (Age)' Height= 'Größe in Inch (Height)'
Weight= 'Gewicht in Pound (Weight)'
Inhalt der generierten Macrovariablen &newlabel
Verwendung im proc print
Alter in Größe in Gewicht in
Vorname Geschlecht Jahren Inch Pound
Obs (Name) (Sex) (Age) (Height) (Weight)
1 Alfred M 14 69.0 112.5
2 Alice F 13 56.5 84.0
...
44
Angriff der SAS Kloneditoren unter Windows
Bei langen Programmen muss man oft vor und zurück scrollen, um alle Informationen zusammenzutragen
SAS unter Windows bietet die Möglichkeit, den Editor zu klonen
Im Programmfenster kann man ein zweites Fenster mit dem Inhalt des aktuellen Fensters öffnen:Menü Window (Alt W) - New Window
45
Angriff der SAS Kloneditoren unter Windows
Änderungen im Programmcode werden in beiden Fenstern gleichzeitig durchgeführt, wobei man an zwei verschiedenen Stellen im Programm sein kann
Das zweite Fenster kann ohne Datenverlust einfach wieder geschlossen werden
Erst beim Schließen des ersten Fensters erfolgt die Nachfrage, ob man speichern möchte
46
Kurz und elegant
Verschiedene DO Schleifen
Möglichkeiten des SELECT Statement
CALL MISSING
47
Verschiedene DO Schleifen
Klassische Anwendung: DO i=1 TO n
Schleifenindex kann aber auch als Variable weiterverwendet werden.
Trennung durch Komma und Sprünge sind möglich
DO iday= 5, 7, 10, 14;
output;
END;
DO proc= "Print", "Freq", "Report";
output;
END;
48
Verschiedene DO Schleifen
Anwendungsbeispiel: Erzeugen eines Dummy-Datensatzes zur Tabellierung aller möglichen Ausprägungen einer Variablen.
DATA dummy;
catord=1; cattxt='Number of discontinuations'; OUTPUT;
catord=2; cattxt='Protocol violation'; OUTPUT;
catord=3; cattxt='Protocol entry criterion not met'; OUTPUT;
catord=4; cattxt='Adverse Event'; OUTPUT;
catord=5; cattxt='Lost to follow-up'; OUTPUT;
RUN;
Version mit einzelnen Zuweisungen:
49
Verschiedene DO Schleifen
PROC FORMAT;
value txtf
1 = 'Number of discontinuations'
2 = 'Protocol violation'
3 = 'Protocol entry criterion not met'
4 = 'Adverse Event'
5 = 'Lost to follow-up‘;
RUN;
DATA dummy2;
DO catord=1 TO 5;
cattxt=put(catord, txtf.);
OUTPUT;
END;
RUN;
Version mit Variablennamen in DO-Schleife und Format:
50
Möglichkeiten des SELECT Statement
Mehrere Elemente im SELECT Statement select(a);
when (3,4,5) put ">= 3";
when (1,2) put "<= 2";
otherwise;
end;
Ohne Klammer hinter SELECT,komplette Bedingung direkt in WHEN Klammer
select;
when (a IN (3,4,5)) put ">= 3";
when (b IN (1,2)) put "<= 2";
otherwise;
end;
51
CALL MISSING
DATA dummy;
LENGTH num1 num2 4 char1-char3 $10 ;
CALL MISSING(num1, num2, char1, char2, char3);
RUN;
Neue Funktion zum Initialisieren (ab SAS 9.2)
Weist einer Liste von Variablen missing values zu
Die Variablen können numerisch oder alphanumerisch sein
� entspricht num1 =.; char1 = " ";
num2 =.; char2 = " ";
char3 = " ";
52
Nützliche Funktionen
SMALLEST und LARGEST (ab SAS 9)
STRIP (ab SAS 9)
COMPBL (ab SAS 8)
SUBSTRN (ab SAS 9)
53
SMALLEST und LARGEST (ab SAS9)
Mit MIN und MAX wird der kleinste bzw. größte Wert einer Zahlenreihe ermittelt
SMALLEST und LARGEST ermitteln den x-kleinsten bzw. x-größten Wert einer Zahlenreihe.
Syntax: SMALLEST (k, value-1<,value-2 ...>) LARGEST (k, value-1<,value-2 ...>)
k kann eine Zahl, eine Variable oder ein Ausdruck sein
Missings werden ans Ende sortiert. Es werden immer erst die vorhandenen Werte genommen und erst wenn die Anzahl von k größer ist als die Anzahl der vorhandenen Werte wird missing ausgegeben.
54
SMALLEST und LARGEST (ab SAS9)
Wenn erstes Argument von Largest/Smallest=1, dann gleiches Ergebnis wie max/min
4
1237893
4564562
7891231
LARGESTSMALLESTk
do k = 1 to 4;
xklein = SMALLEST (k, 456, 789, ., 123);
xgross = LARGEST (k, 456, 789, ., 123);
output;
end;
55
STRIP (ab SAS9)
Führende und abschließende Leerzeichen werden entfernt
Leerzeichen innerhalb des Arguments bleiben
Verkürzung gegenüber SAS8: left(trim(text))
Syntax: strip(text)
svar="*"||STRIP(" Text1 Text2 ")||"*";
� *Text1 Text2*
56
COMPBL (ab SAS8)
Syntax: compbl(text)
Mehrfache Leerzeichen werden durch nur ein Leerzeichen ersetzt
cvar="*"||COMPBL(" Text1 Text2 ")||"*";
� * Text1 Text2 *
57
Vergleich STRIP und COMPBL
* Text1 Text2 *COMPBL
*Text1 Text2*STRIP
* Text1 Text2 * Text
Zur Lesbarkeit ist der Text hier jeweils umrahmt von *
58
SUBSTRN (ab SAS9)
Verwandt mit SUBSTR Funktion, verhält sich anders bei ‘ungültigen’ Argumenten (z.B. negative Startposition, negative Textlänge) � SUBSTRN ist robuster
Syntax: SUBSTRN (Text, Position <, Länge>)
• Text: Zeichenkette. Wenn numerisch � Umwandlung(BEST32, Leerzeichen entfernt an Anfang und Ende)
• Position: Startposition für Extraktion im textwenn <0 dann wird Ergebnis abgeschnitten,Anfang=erstes Zeichen im Text, Länge wird angepasst
• Länge: Länge der zu extrahierenden Zeichenkettewenn nicht definiert: von Position bis Textende, wenn länger als Text, dann bis Textende
Länge der Ausgabevariable: Wenn nicht vorher festgelegt, dann Länge des ersten Argumentes
59
Vergleich SUBSTRN und SUBSTR
Wenn das erste Argument numerisch ist
data substrn;
vsubstr = "*" || SUBSTR(1234.5678,2,6) || "*";
vsubstrn = "*" || SUBSTRN(1234.5678,2,6) || "*";
run;
Ergebnis: vsubstr =* 1234*
vsubstrn=*234.56*
Stellenübersicht123456789012
1234.5678
1234.5678
60
Vielen Dank für Ihre Aufmerksamkeit!
Sabine Erbslöh, Christina Gelhorn
Accovion GmbH, Eschborn