Equivalent to SAS function repeat in PROC IML - string

I want to define a string in a PROC IML, say "aaaaa" (five "a").
In a DATA step, I would use the repeat() function, which creates a string repeating substrings, as explained in the documentation.
data _null_;
x=repeat('a',4); /* string with five 'a' */
put x;
run;
However, in SAS/IML, the repeat() function is different : it creates a matrix repeating elements of another one (documentation here).
So if I use this function, I will get a vector with five "a" elements.
proc iml;
x=repeat('a',5); /* 5 'a' strings */
print x;
quit;
In that example, I could obviously not bother and go directly with :
x="aaaaa";
But what if I needed a larger string (say 100 "a" for example) ? I could also create it outside of the PROC IML and import it after but there must be a more clever way to address the problem, isn't there ?

There is no need to write a loop. Use the ROWCATC function to concatenate the elements across columns:
proc iml;
N = 10;
x = rowcatc(repeat("a", 1, N)); /* repeat 'a' N times */
print x (nleng(x))[L="Length"];
A slightly harder problem is to concatenate elements and insert some sort of delimiter beteen the elements (blanks, comas, etc). That problems is discussed in the article "Convert a vector to a string."

As IML works with matrices, that is what you normally would want.
To get columns instead of rows:
proc iml;
x=repeat('a', 1, 5);
print x;
quit;
x
a a a a a
You could convert the vector to string using a loop. But in that case it would make more sense to skip repeat and directly use a loop to produce a string:
proc iml;
x="";
do i = 1 to 5;
x = x + 'a';
end;
print x;
quit;
x
aaaaa

Related

Writing a large list of short integers with python

I have a large list of values, which I want written to a file, as short integers.
I want to do this efficiently, and in Python3.
One value at a time, is possible using the struct module:
struct.pack( "h", val )
It is possible to prefix the format entry with a count, like so:
struct.pack( "4h", val0,val1,val2,val3 )
But when I try to construct the format dynamically, and write it in one go, I can't feed in a list.
For example:
values = [ x for x in range(100) ]
fmt = "%dh" % ( len(values), )
p = struct.pack( fmt, values )
Will give the error: struct.error: pack expected 100 items for packing (got 1)
How can I efficiently dump a large number of short integers into a file?
Basically, the Python equivalent of the C code:
short values[100];
fwrite( values, sizeof(values), 1, f);
Or am I forced to write these values one at a time if I use Python?
Just changing one character:
p = struct.pack(fmt, *values)

dealing with array of characters . how can i define an array without declaring its size?

I have an assignment to write a c++ program that:
declares an array named gamma of type char.
declares an array named vowels of type char.
prompts the user to input n characters in the array gamma.
defines a function named save vowels that determines and return the number of vowels letters in the gamma array and save them in the vowels array.
I already tried to write this but I got many errors especially with gamma array.
#include<iostream>
using namespace std;
void main()
{
char gamma[];
int i;
cout<<"insert characterst//insert -1 when you finish "<<endl;
while(i!=-1)
{
cin>>i;
gamma[]='i';
}
char vowels[]={'a','e','i','o','u'};}
You look to be well on your way.
declares an array named gamma of type char.
char gamma[];
This part is almost correct although the array has a size of 0. If you wanted to give it a size of 10, you would change it to
char gamma[10];
declares an array named vowels of type char.
This part is fine as is.
char vowels[]={'a','e','i','o','u'};
The list automatically gives vowels a size of 5 and assigns the values.
prompts the user to input n characters in the array gamma.
You look to have this down perfectly with the cout/cin lines. One small nitpick is that you should prefer using "\n" at the end of a cout instead of endl as it is much faster.
cout << "insert characterst//insert -1 when you finish\n";
You also need to change how you write to your array. You have to specify the index in which you want to write.
gamma[0] = 3; // Set the first element of gamma to 3
gamma[2] = 11;// Set the third element of gamma to 11
You'll need to add a counter to your while loop to know which position of gamma you are writing to
int counter = 0;
while(...) {
cin >> i;
gamma[counter] = i;
counter++;
}
You also need to add a check to your while loop that makes sure you don't write past the end of your gamma array. This is likely the cause of your errors.
For example, if we gamma is defined with a size of 10 it can only hold 10 characters. Trying to write 11 characters to gamma will likely cause the program to crash. Try adding a check like:
while( i != -1 && counter < 10) // where 10 is capacity of gamma
defines a function named save vowels that determines and return the number of vowels letters in the gamma array and save them in the vowels array.
You didn't give anything in your question on this point so I can't really help you out here.

AHK Remove every second char from variable

I need a code on AHK
I have a variable look like this:
CYOMYACHOAYJGUGRYYQNYB
I need to get this:
YMAHAJURYNB
I meen, i need every second char from a variable. Thank in advance
Var := "CYOMYACHOAYJGUGRYYQNYB"
Loop, Parse, Var ; retrieves each character from the variable, one at a time
{
If (Mod(A_Index, 2) = 0) ; If A_Index is even (the remainder after division by 2 is 0)
NewVar .= A_LoopField ; add the retrieved character to the new variable
}
MsgBox %NewVar%
This works for me. I am using bit wise to determine if the index of the array of letters, given to me by StrSplit(TestString), is even or odd as I loop through them. I used this forum post for the bitwise logic. Then I concatenate if the line is even. So if index&1=0 will be true when the number is even, thus giving me every other letter to concatenate into NewString with this line NewString=%NewString%%letter%. Feel free to uncomment out the message box lines by removing the ; to better see how the loop parses the array.
TestString := "ABCD"
word_array := StrSplit(TestString)
NewString:=""
For index, letter in word_array{
if index&1=0
{
;MsgBox, %letter% added
NewString=%NewString%%letter%
;Msgbox, %NewString%
}
}
MsgBox, %NewString%
As you don't specify any language, I'll answer in pseudocode:
set counter to 1
set result to empty string
for every char in string:
if counter is even:
append char to result
increment counter by 1
user3419297 beat me to it, but mine is even easier:
InputBox, x, What Variable?, Enter Variable:
loop, % StrLen(x)
If mod(A_Index,2)=0
y.=substr(x,A_Index,1)
msgbox %y%
Clipboard := y
You input the variable in a dialog, and the result is shown, and put in clipboard. Hth,
EDIT: I like the bitwise logic from Zack Tarr! Substitute for the "if" above:
If A_Index&1=0
The rest is the same.

Sort letters in string alphabetically- SAS

I would like to sort the letters in a string alphabetically.
E.g.
'apple' = 'aelpp'
The only function I have seen that is somewhat similar is SORTC, but I would like to avoid splitting each word into an array of letters if possible.
Joe's right - there is no built-in function that does this. You have two options here that I can see:
Split your string into an array and sort the array using call sortc. You can do this fairly painlessly using call pokelong provided that you have first defined an array of sufficient length.
Implement a sorting algorithm of your choice. If you choose to go down this route, I would suggest using substr on the left of the = sign to change individual characters without rewriting the whole string.
Here's an example of how you might do #1. #2 would be much more work.
data _null_;
myword = 'apple';
array letters[5] $1;
call pokelong(myword,addrlong(letters1),5); /*Limit # of chars to copy to the length of array*/
call sortc(of letters[*]);
myword = cat(of letters[*]);
putlog _all_;
run;
N.B. for an array of length 5 as used here, make sure you only write the first 5 characters of the string into memory at the start of the array when using call pokelong in order to avoid overflowing past the end of the array - otherwise you could overwrite some other arbitrary section of memory when processing longer values of myword. This could cause undesirable side effects, e.g. application / system crashes. Also, this technique for populating the array will not work in SAS University Edition - if you're using that, you'll need to use a do-loop instead.
I did a little test of this - sorting 2m random words of length 100 consisting of characters chosen from the whole ASCII printable range took about 15 seconds using a single CPU of a several-years-old PC - slightly less time than it took to create the test dataset.
data have;
length myword $100;
do i = 1 to 2000000;
do j = 1 to 100;
substr(myword,j,1) = byte(32 + int(ranuni(1) * (126 - 32)));
end;
output;
end;
drop i j;
run;
data want;
set have;
array letters[100] $1;
call pokelong(myword,addrlong(letters1),100); /*Limit # of chars to copy to the length of array*/
call sortc(of letters[*]);
myword = cat(of letters[*]);
drop letters:;
run;

How do I put variable values into a text string in MATLAB?

I'm trying to write a simple function that takes two inputs, x and y, and passes these to three other simple functions that add, multiply, and divide them. The main function should then display the results as a string containing x, y, and the totals.
I think there's something I'm not understanding about output arguments. Anyway, here's my (pitiful) code:
function a=addxy(x,y)
a=x+y;
function b=mxy(x,y)
b=x*y;
function c=dxy(x,y)
c=x/y;
The main function is:
function [d e f]=answer(x,y)
d=addxy(x,y);
e=mxy(x,y);
f=dxy(x,y);
z=[d e f]
How do I get the values for x, y, d, e, and f into a string? I tried different matrices and stuff like:
['the sum of' x 'and' y 'is' d]
but none of the variables are showing up.
Two additional issues:
Why is the function returning "ans 3" even though I didn't ask for the length of z?
If anyone could recommend a good book for beginners to MATLAB scripting I'd really appreciate it.
Here's how you convert numbers to strings, and join strings to other things (it's weird):
>> ['the number is ' num2str(15) '.']
ans =
the number is 15.
You can use fprintf/sprintf with familiar C syntax. Maybe something like:
fprintf('x = %d, y = %d \n x+y=%d \n x*y=%d \n x/y=%f\n', x,y,d,e,f)
reading your comment, this is how you use your functions from the main program:
x = 2;
y = 2;
[d e f] = answer(x,y);
fprintf('%d + %d = %d\n', x,y,d)
fprintf('%d * %d = %d\n', x,y,e)
fprintf('%d / %d = %f\n', x,y,f)
Also for the answer() function, you can assign the output values to a vector instead of three distinct variables:
function result=answer(x,y)
result(1)=addxy(x,y);
result(2)=mxy(x,y);
result(3)=dxy(x,y);
and call it simply as:
out = answer(x,y);
As Peter and Amro illustrate, you have to convert numeric values to formatted strings first in order to display them or concatenate them with other character strings. You can do this using the functions FPRINTF, SPRINTF, NUM2STR, and INT2STR.
With respect to getting ans = 3 as an output, it is probably because you are not assigning the output from answer to a variable. If you want to get all of the output values, you will have to call answer in the following way:
[out1,out2,out3] = answer(1,2);
This will place the value d in out1, the value e in out2, and the value f in out3. When you do the following:
answer(1,2)
MATLAB will automatically assign the first output d (which has the value 3 in this case) to the default workspace variable ans.
With respect to suggesting a good resource for learning MATLAB, you shouldn't underestimate the value of the MATLAB documentation. I've learned most of what I know on my own using it. You can access it online, or within your copy of MATLAB using the functions DOC, HELP, or HELPWIN.
I just realized why I was having so much trouble - in MATLAB you can't store strings of different lengths as an array using square brackets. Using square brackets concatenates strings of varying lengths into a single character array.
>> a=['matlab','is','fun']
a =
matlabisfun
>> size(a)
ans =
1 11
In a character array, each character in a string counts as one element, which explains why the size of a is 1X11.
To store strings of varying lengths as elements of an array, you need to use curly braces to save as a cell array. In cell arrays, each string is treated as a separate element, regardless of length.
>> a={'matlab','is','fun'}
a =
'matlab' 'is' 'fun'
>> size(a)
ans =
1 3
I was looking for something along what you wanted, but wanted to put it back into a variable.
So this is what I did
variable = ['hello this is x' x ', this is now y' y ', finally this is d:' d]
basically
variable = [str1 str2 str3 str4 str5 str6]

Resources