Hi!
I am using SAS EG 7.12 (but not using any real EG features - just coding as if I am in Base SAS).
I have a variable that is a 48-character string of letter codes (origstring). I am trying to split the string into 2 parts - the part before and up to a certain position, and the part after a certain position. But the position in question is different for each record. I have a numeric variable posnum that contains the position number where I want to split the string.
So my code is:
length firstpart secondpart $ 48;
firstpart=substr(origstring,1,posnum); /* read origstring from position 1 for a length of the value of posnum */
secondpart=substr(origstring, posnum+1); /* read origstring starting at posnum+1 to the end */
But firstpart and secondpart always end up as just 1 character. I think it is the first character of each part, but there is a lot of repetition in the letter codes so I can't be sure.
I have already tried left justifying origstring. There are no notes in the Log.
Is using a variable name as the position and length arguments of substr() not allowed? How else can I do this?
Thanks!
You are not setting POSNUM in your code. Where is the value coming from?
Are you sure that ORIGSTRING is as long as you think it is? Perhaps it only has length of 1 or 2?
Make sure that the LENGTH statement is the first place that SAS sees those variables. You cannot change the length of a character variable after the data step compiler has already determined the length to use for it.
You are not setting POSNUM in your code. Where is the value coming from?
Are you sure that ORIGSTRING is as long as you think it is? Perhaps it only has length of 1 or 2?
Make sure that the LENGTH statement is the first place that SAS sees those variables. You cannot change the length of a character variable after the data step compiler has already determined the length to use for it.
Thanks Tom! Moving the length statement seems to have done the trick, although I'm not totally sure why.
orgstring was definitely 48 characters before - I could see all the letters if I displayed the values - but I had never formally defined it. I put a length statement for it and firstpart and secondpart right at the top of my data step, and now everything seems to be working.
(To answer your other question - posnum was populated using code that I did not show because it was working. I could see it had all the right values in it.)
Thanks again.
One of the user friendly features of SAS is that you do not need to define variables before using them in your code.
However a draw back of this is that SAS might define the variable differently than you intended if you are not careful.
For example what if had some type of DO loop that was testing your new variable.
do until(firstpart=' ');
...
firstpart=substr(original,1,position);
...
end;
Now the first place that SAS sees FIRSTPART is in the comparison to the constant string of one character length. So it will make FIRSTPART a character variable of length $1.
The third argument to substr is the number of characters to get, not a character position. Is that the confusion?
Example data and the full code of the data step you are using will likely help.
Instructions here: https://communities.sas.com/t5/SAS-Communities-Library/How-to-create-a-data-step-version-of-your-dat... will show how to turn an existing SAS data set into data step code that can be pasted into a forum code box using the {i} icon or attached as text to show exactly what you have and that we can test code against.
Please post code in a code box opened with either the {I} or "running man" icon. The forum will reformat text in the main windows and sometimes remove things needed for code to run or may result in something slightly different than what you have run.
You might also check on what FORMAT is assigned to your variables Firstpart and Secondpart. If somehow you have a format of $1. it will only display by default one character even though there are more characters in the value.
data example; x='Somewhat longish string value'; format x $1.; run; proc print data=example; run;
But using a different format at use shows more characters.
proc print data=example; format x $10.; run;
Using one of the table viewing tools will also only show one character.
Note that there are very few situations where it makes sense to permanently attach $xx. format to character variables. SAS already knows how to display character strings and does not need special formatting instructions for them.
To REMOVE a format from a variable use a FORMAT statement without any format specification.
format x ;
@Tom wrote:
Note that there are very few situations where it makes sense to permanently attach $xx. format to character variables. SAS already knows how to display character strings and does not need special formatting instructions for them.
To REMOVE a format from a variable use a FORMAT statement without any format specification.
format x ;
Understand and agree, but we have seen examples where that is the issue in the past.
It may be helpful to post the full log using the {i} icon.
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!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Select SAS Training centers are offering in-person courses. View upcoming courses for: