Hallo zusammen,
gibt es eine Option mit der ich dem SS beibringen kann, dass es aus einer Datei das Char-Feld 'name' sauber und korrekt einliest, obwohl es nur einen Punkt (also das Zeichen .) enthält.
Ein Beispiel:
data test;
length name $10.;
input name $ ;
LIST; /* Eingabe-Daten im Log ausgeben, hier sieht ales gut aus */
cards;
Meier
Müller
.
Schmitt
;
run;
Ausgabe der Test-Daten: Im 3. Satz ist die Variable 'Name' komplett leer, obwohl sie mit dem Zeichen '.' gefüllt ist.
proc print data=test;
run;
Die Ausgabe mit einem data-_null_-Step hilft auch nicht weiter: Im 3. Satz ist Name immer noch leer:
data _null_;
set test;
put name=;
run;
Die Lst- bzw- Log-Ausgabe bitte selbst erzeugen.
Was kann ich tun, damit der Wert '.' sauber eingelesen bzw. ausgegeben wird?
Wir nutzen hier SAS 9.4 (TS1M3), Client/Server mit Windows-Clients und einem Linux-Server.
Der Effekt tritt sowohl auf dem Client als auch auf dem Server auf.
Viele Grüße
Hans
Hallo Hans,
das funktioniert, indem man noch ein Informat spendiert, damit SAS weiß, was es einlesen soll:
data test;
length name $10.;
informat name char10.;
input name $ ;
LIST; /* Eingabe-Daten im Log ausgeben, hier sieht alles gut aus */
cards;
Meier
Müller
.
Schmitt
;
run;
Viele Grüße
Michael
Hallo Michael,
danke für die Lösung. Bisher habe ich den informat-Befehl eher für verzichtbaren Luxus gehalten.
Ich habe es gleich ausprobiert und es klappt.
Leider klappt es nur in meinem Beispiel!
In meinem echten Code bleibt das Feld, dort heitßt es name1, unverändert leer.
Ich vermute es gibt einen Unterschied zwischen cards und dem echten aus einer Datei einlesen.
Ich habe meinen echten Code soweit abgespeckt, dass er überschaubar wird, aber der Effekt immer noch auftritt:
filename datei03 "C:\musterdaten.txt";
data test;
infile datei03 obs=999999999 LRECL=555 missover pad end=end ;
length kundnum $10 anldat_a $ 8 loevm_A $ 1 sperr $ 1 ;
length anrede $ 15 titel $ 15;
length name1 name2 name3 $ 40;
informat name1 name2 name3 char40.;
input kundnum $10. anldat_A $8. loevm_A $1. sperr $1.
anrede $15. titel $15.
name1 $40. name2 $40. name3 $40. strasse $60. plz $10. ort $40.
;
output;
run;
proc print data=test;
run;
Die Test-Daten sehen so aus:
004711471019990303xsFirma Name1 Name2 Strasse mit Hnr PLZ Ort
004711471119990202 Firma . Wilhelmstr. 1 54321 Musterweiler
004711471219990101 Firma Mustername AG Spezialfabrik Emil-Meier-Str. 1 12345 Musterort
Damit bekomme ich trotz dem informat-Befehl immer noch ein leeres Feld statt den Punkt als Befüllung.
Viele Grüße und vielen Dank
Hans
Das Format im input-Statement übersteuert das Format aus dem informat-Statement. Entweder an beiden Stellen das gleiche Format verwenden, oder im input gar keines, je nachdem ob formatted input notwendig ist (fixe Spalten) oder nicht.
Stimmt, da war ich wohl nicht ganz bei der Sache.... einfach im Input das Char-Format verwenden hätte im obigen Beispiel auch völlig ausgereicht, wenn man kein Informat verwenden will.
Hallo,
ich habe weiter experimentiert und seltsamerweise hilft das informat auch mit dem cards-Befehl nichts:
data aaa;
length kundnum $10 anldat_a $ 8 loevm_A $ 1 sperr $ 1 ;
length anrede $ 6 ;
length name1 name2 $ 15;
informat name1 name2 char15.;
input kundnum $10. anldat_A $8. loevm_A $1. sperr $1.
anrede $6.
name1 $15. name2 $15. strasse $18. plz $6. ort $12.
;
cards;
004711471019990303xsFirma Name1 Name2 Strasse mit Hnr PLZ Ort
004711471119990202 Firma . Wilhelmstr. 1 54321 Musterweiler
004711471219990101 Firma Mustername AG Spezialfabrik Emil-Meier-Str. 1 12345 Musterort
;
run;
proc print data=aaa;
run;
Viele Grüße und vielen Dank
Hans
Hallo Kurt,
ich war so mit experimentieren und dem erstellen des zweiten Kommentars beschäftigt, dass ich Deinen Eitrag gar nicht gesehen habe.
Danke für Deine Hilfe.
Jetzt klappt es auch im echten Code. Wie so oft gilt: Kaum macht man es richtig, schon funktioniert's.....
Danke noch einmal!
Viele Grüße
Hans
Hallo,
nur noch als Ergänzung:
Im Beispiel handelt es sich um eine Rohdaten-Datei, in der die unterschiedlichen Werte nicht durch ein Trennzeichen getrennt sind, sondern immer an dedizierten Spalten beginnen. In diesem Fall ist man ganz 'sauber', wenn man spaltenorientiert einliest, d.h., wenn man bei jedem Wert, den man auslesen will, angibt, an welcher Spalte er beginnt und wo er endet.
Der Programmcode sähe dann so aus:
data test;
infile datei03 obs=999999999 LRECL=555 missover pad end=end ;
length
kundnum $10
anldat_a $8
loevm_A $1
sperr $1
anrede $15
name1
name2 $40
strasse $40
plz $5
ort $40
;
input
kundnum $ 1 - 10
anldat_A $ 11 - 18
loevm_A $ 19 - 19
sperr $ 20 - 20
anrede $ 21 - 26
name1 $ 27 - 41
name2 $ 42 - 56
strasse $ 57 - 74
plz $ 75 - 80
ort $ /* Den Rest der Zeile als 'Ort' lesen */
;
output;
run;
proc print data=test;
run;
Abschließende Hinweise:
Viele Grüße
Andreas
Ein einzelner Punkt ist ein Spezialfall und steht in einem SAS Kontext oftmals fuer Missing Value.
$CHAR. ist ein Informat welches Punkte nicht zu blanks konvertiert.
Mit dem LIST command wird der Input Buffer in den Log rausgeschrieben. Der Punkt wird erst konvertiert, wenn man eine Variable gegen diesen Input Buffer "mapt".
data test;
infile datalines dlm=' ' truncover;
input name :$char10.;
cards;
Meier
Müller
.
Schmitt
;
run;
Hallo zusammen,
@Andreas
Danke für die Info, aber ich bleibe erst mal bei unserer bisherigen Vorgehensweise. Die erscheint mit Änderungsfreundlicher zu sein.
Danke für die Details zum char-Format. Damit ist das 'seltsame' Verhalten geklärt. Dank dem Link bin ich noch auf eine Gemeinheit bei der Verwendung vom char-Format gestoßen:
If you use $CHARw. in an INFORMAT or ATTRIB statement within a DATA step to read list input, then by default SAS interprets any blank embedded within data as a field delimiter, including leading blanks.
Zum Glück habe ich aus Gewohnheit kein informat verwendet .... !
Viele Grüße
Hans
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 16. Read more here about why you should contribute and what is in it for you!