5

improved formatting,I am a bit stuck where I am not able to extract the last 4 characters of the string., when I write :-

indikan=substr(Indikation,length(Indikation)-3,4);

It is giving invalid argument.
how to do this?

Dharmesh Porwal
  • 1,406
  • 2
  • 12
  • 21
user3658367
  • 641
  • 1
  • 14
  • 30
  • To be more likely to get helpful answers, please include sample data that reproduces the problem. – Joe Jan 09 '15 at 21:38

6 Answers6

5

This code works:

data temp;
indikation = "Idontknow";
run;

data temp;
set temp;
indikan = substrn(indikation,max(1,length(indikation)-3),4);
run;

Can you provide more context on the variable? If indikation is length 3 or smaller than I could see this erroring or if it was numeric it may cause issues because it right justifies the numbers (http://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a000245907.htm).

JJFord3
  • 1,976
  • 1
  • 25
  • 40
  • Use `substrn()` instead if you need strings of 3 characters or less to also be returned. Also, if the string is empty, `substrn()` will handle this elegantly. – Robert Penridge Jan 09 '15 at 18:56
  • Hmm, I didn't realize substrn was so handy - I only knew about the null string return. I'm not sure I understand why it's crammed full of other fun things, like better numeric handling and automatic truncation, but it's super handy @RobertPenridge! – Joe Jan 09 '15 at 21:35
  • @Joe Yeah I only just discovered it after looking at this answer as well. Just like SAS to give the more useful function the less intuitive name =). I was actually checking the doc to see if regular `substr()` would accept a negative value as a start position (it doesn't) when I came across `substrn()`. I definitely have some code to go and update now! – Robert Penridge Jan 09 '15 at 23:44
2

If it's likely to be under four characters in some cases, I would recommend adding max:

indikan = substrn(indikation,max(1,length(indikation)-3),4);

I've also added substrn as Rob suggests given it better handles a not-long-enough string.

Joe
  • 62,789
  • 6
  • 49
  • 67
1

Or one could use the reverse function twice, like this:

data _null_;

   my_string = "Fri Apr 22 13:52:55 +0000 2016";

   _day   = substr(my_string, 9, 2);
   _month = lowcase(substr(my_string, 5, 3));

   * Check the _year out;
   _year  = reverse(substr(reverse(trim(my_string)), 1, 4));

   created_at = input(compress(_day || _month || _year), date9.);

   put my_string=;
   put created_at=weekdatx29.;
run;
0

Wrong results might be caused by trailing blanks: so, before you perform substr, strip/trim your string:

indikan=substr(strip(Indikation),length(strip(Indikation))-3);

must give you last 4 characters

Gabit Kemelov
  • 106
  • 1
  • 8
0

Or you can try this approach, which, while initially a bit less intuitive, is stable, shorter, uses fewer functions, and works with numeric and text values:

indikan = prxchange("s/.*(.{4}$)/$1/",1,indikation);
-1
data temp;
input trt$;
cards;
treat123
treat121
treat21
treat1
treat1
trea2
;run;

data abc;
set temp;
b=substr(trt,length(trt)-3);
run;
[Output]

Output:

https://i.stack.imgur.com/WVB0A.jpg

hering
  • 1,956
  • 4
  • 28
  • 43