Date: Mon, 3 Mar 2008 11:49:59 -0500
Reply-To: "Howard Schreier <hs AT dc-sug DOT org>"
<schreier.junk.mail@GMAIL.COM>
Sender: "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From: "Howard Schreier <hs AT dc-sug DOT org>"
<schreier.junk.mail@GMAIL.COM>
Subject: Re: AW: read out a string
On Mon, 3 Mar 2008 09:16:18 -0500, Peter Crawford
<peter.crawford@BLUEYONDER.CO.UK> wrote:
>On Mon, 3 Mar 2008 09:02:59 -0500, Howard Schreier <hs AT dc-sug DOT org>
><schreier.junk.mail@GMAIL.COM> wrote:
>
>>On Mon, 3 Mar 2008 12:40:18 +0100, Stefan Pohl <stefan.pohl@ISH.DE> wrote:
>>
>>>Dear Howard,
>>>
>>>how is your code to modify that it can handle this input
>>>
>>>data have1;
>>> input ids $50.;
>>> cards;
>>>[1 226] [227 390] [391 419] [420 435] [436 439]
>>>[1 226] [227 390] [391 435] [436 439]
>>>[1 226] [227 390] [391 439]
>>>[1 390] [391 439]
>>>[1 439]
>>> ;
>>>run;
>>>
>>>Thank you for your help.
>>
>>Short answer: Change the F informat to D.
>>
>>Explanation: The documentation for the w.d informat states that BESTw.d,
>>Dw.d, Ew.d, Fw.d are all aliases for w.d. However, it appears to F has a
>>default width of 1 whereas the other 3 have default width 12. I run this
>code:
>>
>> data _null_;
>> best = input('1234567890123',best.);
>> d = input('1234567890123', d.);
>> e = input('1234567890123', e.);
>> f = input('1234567890123', f.);
>> put +3 _all_;
>> run;
>>
>>I see
>>
>> best=123456789012 d=123456789012 e=123456789012 f=1 _ERROR_=0 _N_=1
>>
>>So the F informat is not exactly an alias for the others.
>>
>>>
>>>Stefan.
>>>
>>>
>>>
>>>> I agree with Gerhard. Put aside macro for now, and
>>>> concentrate on the DATA step and/or PROC code needed to solve
>>>> the problem. Then go back and macro-ize if there is really
>>>> need for that.
>>>>
>>>> The notation with square brackets and concatenation of
>>>> multiple pairs may be familiar from the literature, but it is
>>>> not useful in SAS. So first extract all of the values into a
>>>> nice data structure. Here's one way:
>>>>
>>>> data have;
>>>> input ids $50.;
>>>> cards;
>>>> [1 2] [3 3] [4 4] [5 5] [6 6] [7 7] [8 8] [9 9]
>>>> [1 4] [5 5] [6 6] [7 7] [8 8] [9 9]
>>>> [1 4] [5 5] [6 8] [9 9]
>>>> [1 9]
>>>> ;
>>>>
>>>> data need(keep = i j id1 id2);
>>>> set have;
>>>> i = _n_;
>>>> ids = compress(tranwrd(ids,'] [','|'),'[]');
>>>> do j = 1 by 1;
>>>> pair = scan(ids,j,'|');
>>>> if missing (pair) then leave;
>>>> ID1 = input(scan(pair,1,' '),f.);
>>>> ID2 = input(scan(pair,2,' '),f.);
>>>> output;
>>>> end;
>>>> run;
>>>>
>>>> Result:
>>>>
>>>> Obs i j ID1 ID2
>>>>
>>>> 1 1 1 1 2
>>>> 2 1 2 3 3
>>>> 3 1 3 4 4
>>>> 4 1 4 5 5
>>>> 5 1 5 6 6
>>>> 6 1 6 7 7
>>>> 7 1 7 8 8
>>>> 8 1 8 9 9
>>>> 9 2 1 1 4
>>>> 10 2 2 5 5
>>>> 11 2 3 6 6
>>>> 12 2 4 7 7
>>>> 13 2 5 8 8
>>>> 14 2 6 9 9
>>>> 15 3 1 1 4
>>>> 16 3 2 5 5
>>>> 17 3 3 6 8
>>>> 18 3 4 9 9
>>>> 19 4 1 1 9
>>>>
>>>> On Fri, 29 Feb 2008 04:02:47 -0500, Gerhard Hellriegel
>>>> <gerhard.hellriegel@T-ONLINE.DE> wrote:
>>>>
>>>> >On Fri, 29 Feb 2008 09:27:46 +0100, Stefan Pohl
>>>> <stefan.pohl@ISH.DE> wrote:
>>>> >
>>>> >>Dear sas-group,
>>>> >>
>>>> >>I want to read out the information in a string IDs who
>>>> looks like this
>>>> >>
>>>> >>IDs
>>>> >>obs1: [1 2] [3 3] [4 4] [5 5] [6 6] [7 7] [8 8] [9 9]
>>>> >>obs2: [1 4] [5 5] [6 6] [7 7] [8 8] [9 9]
>>>> >>obs3: [1 4] [5 5] [6 8] [9 9]
>>>> >>obs4: [1 9]
>>>> >>
>>>> >>One first idea for a macro readout:
>>>> >>
>>>> >>%MACRO readout(data);
>>>> >>
>>>> >>*obs1;
>>>> >>
>>>> >>%DO i=1 TO 8;
>>>> >>
>>>> >> DATA readout1;
>>>> >> SET &data;
>>>> >> WHERE ID in (1,2); *here the string IDs has to be read out; RUN;
>>>> >>
>>>> >> ....
>>>> >>
>>>> >>%END;
>>>> >>
>>>> >>%MEND readout;
>>>> >>
>>>> >>How can I read out the information in the [...]?
>>>> >>
>>>> >>Best regards, Stefan.
>>>> >
>>>> >
>>>> >Hi Stefan,
>>>> >first I can say, that a macro in that environment might not a good
>>>> >idea,
>>>> >second: mixing macro- and datastep code is a very bad idea!
>>>> >
>>>> >%do i=1 to 8;
>>>> >
>>>> >will never do what you want, whatever it is.
>>>> >
>>>> >One question: what are that "IDs"? What do you want to get?
>>>> >Maybe it would be easier to understand, if you provide the desired
>>>> >result, instead of the method you try to get it.
>>>> >
>>>> >Gerhard
>>>>
>>>> __________ NOD32 2911 (20080229) Information __________
>>>>
>>>> This message was checked by NOD32 antivirus system.
>>>> http://www.eset.com
>>>>
>>>>
>
>
>if those [] are to be ignored, add them among the default delimiters...
>
>Why then is the solution more complex than :>>>>>>>>>
>data have1;
> infile cards dlm='[ ]' flowover ;
> input id1 id2 @@ ;
>cards;
>[1 226] [227 390] [391 419] [420 435] [436 439]
>[1 226] [227 390] [391 435] [436 439]
>[1 226] [227 390] [391 439]
>[1 390] [391 439]
>[1 439]
>;
>
>Because the DSD option is not used, consecutive delimiters are treated as
>one.
>I stated the (default) option FLOWOVER, to emphasise that that is the
>required behaviour.
>
>Have I missed some requirement ?
>
>PeterC
I believe the original post specified that a SAS data set with one long
character variable was a given. The DATA HAVE step just modeled that for
testing. Of course one could write it all out to a temporary external file,
then use your solution. And of course, there is always _INFILE_ Magic.
|