BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
rakeshvvv
Quartz | Level 8

I Have dataset with numerical id as variable. I would like to write a code in a such way that i get red colored below out put.

40047915 -------Truncate 40 if it starts with 40 and the length is 8            

40047916

40047917

400032724

400032725

400032726---------- Truncate 400 if it starts with 400 and the length is 9

047915

047916

047917

032724

032725

032726

1 ACCEPTED SOLUTION

Accepted Solutions
jwillis
Quartz | Level 8

This also works.


data work.have;
  input  value 9.;
  format wantval z6.;
  valclen = length(strip(put(value,9.)));
     if valclen = 8 then wantval = value - 40000000; 
     if valclen = 9 then wantval = value - 400000000;
  datalines;
40047915
40047916
40047917
400032724
400032725
400032726
;
run;

View solution in original post

9 REPLIES 9
RW9
Diamond | Level 26 RW9
Diamond | Level 26

Hi,

Data want;

     set have;

     if substr(thevariable,1,2)="40" and length(strip(thevariable))=8 then substr(thevariable,3);

     else if substr(thevariable,1,3)="400" and length(strip(thevariable))=9 then substr(thevariable,4);

run;

You should be aware though your logic seems to overlap as 400 appears for each record.  So only the length check is really necessary, i.e. if length(strip(thevariable))=8 then substr(2..), else sustr(3...).

Just thought also, you could also reverse the string and take the first 8 characters, then reverse again.  Or you could also right() the string, take the last 8 characters and then left e.g  substr(right(thevariable),length(right(thevariable)-8);

rakeshvvv
Quartz | Level 8

Thanks for your reply......is there way that i can take take only last 6 numbers if the barcode starts with 4.....

ex;;

400032735--------032735

400032736-------032736

400032737-------032737

40046812--------046812

jwillis
Quartz | Level 8

I did not test this:

data have;
  input  value 9.;
     length wantval 8; format wantval z6.;
    wantval = substr((put(value,9.)),(length(put(value,9.)) - 6),6);
  datalines;
40047915          
40047916
40047917
400032724
400032725
400032726
;
run;

I did test this and this works:

proc sql; drop table work.have; quit;
data have;
     input  value 9.;
     length wantval  8 ; format wantval  z6.;
    if substr(strip(put(value,9.)),1,1) = '4' then do;
       wantval = substr((strip(put(value,9.))),((length(strip(put(value,9.))) - 6) + 1),6);
    end;
   datalines;
40047915          
40047916
40047917
400032724
400032725
400032726
;

proc print data=work.have;
run;

Message was edited by: James Willis

Tom
Super User Tom
Super User

If it is a number then you can use the MOD() function to get the least significant digits.

want = mod(nid,10**6) ;

But of course if it is numeric there is no way to store the leading zeros in your examples.  You could apply the Z format to have the numbers print with leading zeros.

Haikuo
Onyx | Level 15

If the rule can be interpreted as "regardless of the length of the variable, keep the last 6 digits", then the following can also do:

data test;

     input var $10.;

     newvar=prxchange('s/.*(\d{6})$/$1/',-1,trim(var));

     cards;

40047915

40047916

40047917

400032724

400032725

400032726

;

Regards,

Haikuo

jwillis
Quartz | Level 8

The code below will handle a numeric starting value.


data have;
  input  value $9.;
  length wantval 8; format wantval z6.;
if length(value) = 8 then wantval = input(substr(value,3,6),8.) ;
if length(value) = 9 then wantval = input(substr(value,4,6),8.) ;
  datalines;
40047915          
40047916
40047917
400032724
400032725
400032726
;
run;

proc print data=have;
run;

This works if your original input value has to remain as a number.  The length function only works on character variables.

data have;
  input  value 9. valuec $9.;
  length wantval 8; format wantval z6.;
valuec = put(value,9.);
if length(valuec) = 8 then wantval = input(substr(valuec,3,6),8.) ;
if length(valuec) = 9 then wantval = input(substr(valuec,4,6),8.) ;
  datalines;
40047915          
40047916
40047917
400032724
400032725
400032726
;
run;

proc print data=have;
run;

Message was edited by: James Willis 

jwillis
Quartz | Level 8

This also works.


data work.have;
  input  value 9.;
  format wantval z6.;
  valclen = length(strip(put(value,9.)));
     if valclen = 8 then wantval = value - 40000000; 
     if valclen = 9 then wantval = value - 400000000;
  datalines;
40047915
40047916
40047917
400032724
400032725
400032726
;
run;

stat_sas
Ammonite | Level 13

data have;

input id $ 9.;

datalines;

40047915

40047916

40047917

400032724

400032725

400032726

;

data want;

set have;

id_new=catt('0',mod(id,100000));

run;

Wizard
Calcite | Level 5

here is a simple way using base SAS functions

Data ids;

     infile cards;

     input long_id 9.;

     id = reverse(substr(reverse(put(long_id,9.)),1,6));

cards;

40047915

40047916

40047917

400032724

400032725

400032726

;;;;

run;

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

What is Bayesian Analysis?

Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 9 replies
  • 1361 views
  • 3 likes
  • 7 in conversation