I want to find special characters in a string, remove them from the string, do a calculation, and put that characters back in. Is there an elegant way to do this?
For example, if I have a variable with values:
33.3%
16%
<10%
I want to multiply 1.2 after removing either or both % and <
39.96
19.2
12
and then I need to put the special characters back
39.96%
19.2%
<12%
Maybe we can use index and prxmatch functions..? index(lborres,'<') or index(lborres,'%') ; if prxmatch('m/<|%', lborres) > 0 then do; I'm not sure how I should go about this (or other way)..
Are you looking for something like the following? The answer should be in the variable called "result".
data have;
input text $char10.;
datalines;
33.3%
16%
<10%
;
data want;
set have;
length result $ 10;
retain factor 1.2;
number = compress(text,'.','kd');
product = number * factor;
result = tranwrd(text,cats(number),cats(product));
run;
Kind regards,
Amir.
You won't be able to do this if just remove special characters but you would need to store things like the < somewhere. If all of the values are percentages then putting them back is relatively simple but you may need to address concerns about how many digits to maintain in your re-calculated values. So please specify rules for significant digits.
Note that because you will be adding digits to a character value that you should also tell us what the defined length of the variable is. If the current defined length of a variable is 5 characters then you won't be able to fit 39.96% into the variable as that requires 6 character positions.
Are you looking for something like the following? The answer should be in the variable called "result".
data have;
input text $char10.;
datalines;
33.3%
16%
<10%
;
data want;
set have;
length result $ 10;
retain factor 1.2;
number = compress(text,'.','kd');
product = number * factor;
result = tranwrd(text,cats(number),cats(product));
run;
Kind regards,
Amir.
I can set up rounding and character lengths in another part of the program; should they affect the code/solution? This solution worked. Thank you!
Thanks for marking a post as a solution (not everyone does).
For best practice, I would recommend assigning variable "number" a numeric value before using it in a calculation. That also means you don't have to assign variable "number" a character length (which I didn't do, because I meant to make it a numeric variable).
Further, as @PaigeMiller also pointed out, if you have negative values then "-" can be added to the second argument of the compress() function.
An example implementation of both points is:
number = input(compress(text,'.-','kd'),8.);
Kind regards,
Amir.
I would recommend a little different approach.
You can eliminate from the string any character that is not a number and not a decimal point and not a negative sign via the COMPRESS() function.
Once you have done that, you can use INPUT to turn these character strings into actual numbers, so you can do the multiplication.
Then I would leave them as numbers, and use some format to make the number appear with a % sign or with a < indicator.
I meant to convert variable number to a number, which is why I used the cats() function on it later which formats numerics with the best. format.
Using a format did cross my mind, but some data had one symbol and others had two and it wasn't immediately clear to me what the rule was from what the OP had posted.
Kind regards,
Amir.
@Amir wrote:
I meant to convert variable number to a number, which is why I used the cats() function on it later which formats numerics with the best. format.
Using a format did cross my mind, but some data had one symbol and others had two and it wasn't immediately clear to me what the rule was from what the OP had posted.
Kind regards,
Amir.
I like your solution @Amir , it is very compact and efficient.
With regard to my suggestion to use formats: my general feeling is that numbers ought to be numbers, and if you want a % sign on the end or a < in front, I would certainly use formats for that, although your solution makes it easy to turn it back into character variables with the special symbols. Obviously, if there were a huge set of possible special symbols, like for example if the original text string was '~2.2}', you can't accomodate all these special symbols using formats.
What if special characters are present in between?
want to mask name with Officer12345 keeping special characters
like (Mr). Briane 'O' Conor to (Of).ficer1'2'345
one more example Han & Van to Off & icer12345
Hi @anuajax,
Ideally, it is best practice to create a new question with what you are now asking and you can supply a link back to this question for context.
For each example you have given what result do you want to see and what did you get when you tried the existing solution?
Also, when supplying data, it is a lot easier for everyone to help you if you supply data using a data step with datalines, as can be seen in the solution.
Thanks & kind regards,
Amir.
Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.
Register today!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: