How do you sort the values by ascending order when concatenating for SAS?
eg. In this example I am trying to acsend values for aeacnoth1_std1, aeacnoth2_std, etc.....
if cmiss( aeacnoth1_std, aeacnoth2_std)=0
then aeacolst=strip(aeacnoth1_std)||','||strip(aeacnoth2_std);
if cmiss( aeacnoth1_std, aeacnoth2_std, aeacnoth3_std)=0
then aeacolst=strip(aeacnoth1_std)||','||strip(aeacnoth2_std)||','||strip(aeacnoth3_std);
if cmiss( aeacnoth1_std, aeacnoth2_std, aeacnoth3_std, aeacnoth4_std)=0
then aeacolst=strip(aeacnoth1_std)||','||strip(aeacnoth2_std)||','||strip(aeacnoth3_std)||','||strip(aeacnoth4_std);
One possible approach:
Declare an array containing all the variables you want to concatenate
Sort the array into the desired order
Concatenate the array
The hard part is step 2, as SAS 9.1 or earlier doesn't provide any direct way of doing this. You might find this paper useful, or just Google for 'sas sort array' and see what comes up:
http://www2.sas.com/proceedings/sugi26/p096-26.pdf
EDIT: if you have SAS 9.2 or later, you can use call sortc to sort the array:
http://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a003106052.htm
Related
I'm having a bit of difficulty with a problem I'm having. I have an array of names like so:
[Brutananadilewski, Carl]
[Crews, Xander]
[Cartman, Eric]
[Rubio, Daniel]
[Daniels, Julie]
etc. etc.
What I need to do is to create a list of unique names from this list without having first and last names repeated. So I would have the following as a result:
[Brutananadilewski, Daniel]
[Crews, Erix]
[Cartman, Xander]
[Rubio, Carl]
[Jill, Daniels]
The problem I'm having is trying to do this efficiently. My first instint was to use permutation and here is a snippet from the ruby docs
a.permutation(2).to_a #=> [[1,2],[1,3],[2,1],[2,3],[3,1],[3,2]]
The problem is having the following from that example [[1,2],[1,3]]
Theoretically if this was a first/last name this wouldnt work. I couldn't have this:
[Rubio Daniel, Rubio Julie, Rubio Eric]
Has anyone dealt with this before? I'm having an awfully hard time with efficiency and just getting it to work. Help would be appreciated thank you.
You can use transpose as mentioned by 3limin4tor, then shuffle and zip as mentioned by Dave Newton:
surnames, forenames = names.transpose
shuffled_forenames = forenames.shuffle
shuffled_names = shuffled_forenames.zip(surnames)
The desired outcome isn't entirely clear from the question, but if you're trying to create all combinations of first/last names and get a subset of those, you could also use product and uniq to get all the uniq combinations:
names = [
%w(Brutananadilewski Carl),
%w(Crews Xander),
%w(Cartman Eric),
%w(Rubio Daniel),
%w(Daniels Julie)
]
surnames, forenames = names.transpose
all_name_combos = forenames.product(surnames).uniq
You could then use shuffle and sample(INTEGER) to get a subset of those name combinations
all_name_combos.shuffle.sample(5)
I am new to this Middleware and I tried my level best to perform sorting using the flow steps in designer but couldn't make it.Can anybody help me out by giving me direction for how to complete my work?(like the flow steps in order and where i can put the conditions and all)
Thanks.
No need to over-complicate it - use the utilities - pub.document:sortDocuments is what you are looking for.
If you receive stringList as input - convert this into a documentList. This can be done using pub.list:stringListToDocumentList (set the key to 'value')
Use pub.document:sortDocuments to sort the documentList. Remember to specify the key as 'value' once again and compareStringAs as 'numeric'. The order can also be set (ascending/descending)
What do you want to Sort? For Document-Lists you will find a built-in services in the WmPublic Folder.
For String-Lists i would use a Java-Service for Sorting.
Logic behind Sorting in webMethods is same as all other languages. You need LOOP to iterate every string in stringList, BRANCH to compare the two number and then map to the compare result to new StringList.
What format do you have the numbers in? Are they in a flat file or in a string list etc.
I am trying to understand the query plan of MonetDB.
Is there a documentation anywhere where I can find what each instruction stays for?
If not, can anybody tell me what are returning
sql.projectdelta(X_15,X_23,X_25,r1_30,X_27)
and
sql.subdelta(X_246,X_4,X_10,X_247,X_249), for example?
In my query I am sorting the result by two attributes (e.g., by A,B). Can you tell me why the second sort has more parameters than the first?
(X_29,r1_36,r2_36) := algebra.subsort(X_28,false,false);
(X_33,r1_40,r2_40) := algebra.subsort(X_22,r1_36,r2_36,false,false);
Is algebra.subsort returning (oid, columnType) pairs, or just oid?
Thank you!!
Understanding output of the explain SQL statement requires knowledge of the MonetDB Assembly-like Language (MAL).
Concerning functions sql.projectdelta, sql.subdelta, and algebra.subsort, you'll find their signature and a (brief) description in the monetdb lib folder. Ex :
[MonetDB_install_folder]\MonetDB5\lib\monetdb5\sql.mal for all sql functions
[MonetDB_install_folder]\MonetDB5\lib\monetdb5\algebra.mal for all algebra functions
Concerning the different number of parameters for algebra.subsort :
(X_29,r1_36,r2_36) := algebra.subsort(X_28,false,false);
is described as :
Returns a copy of the BAT sorted on tail values, a BAT that specifies
how the input was reordered, and a BAT with group information.
The input and output are (must be) dense headed.
The order is descending if the reverse bit is set.
This is a stable sort if the stable bit is set.
(X_33,r1_40,r2_40) := algebra.subsort(X_22,r1_36,r2_36,false,false);
is described as:
Returns a copy of the BAT sorted on tail values, a BAT that specifies
how the input was reordered, and a BAT with group information.
The input and output are (must be) dense headed.
The order is descending if the reverse bit is set.
This is a stable sort if the stable bit is set.
MAL functions can be overloaded bassed on their return value. algebra.subsort can return 1, 2 or 3 values depending on what you're asking for. Checl algebra.mal for the different possibilities.
As an exercise in python lambdas (just so I can learn how to use them more properly) I gave myself an assignment to sort some strings based on something other than their natural string order.
I scraped apache for version number strings and then came up with a lambda to sort them based on numbers I extracted with regexes. It works, but I think it can be better I just don't know how to improve it so it's more robust.
from lxml import html
import requests
import re
# Send GET request to page and parse it into a list of html links
jmeter_archive_url='https://archive.apache.org/dist/jmeter/binaries/'
jmeter_archive_get=requests.get(url=jmeter_archive_url)
page_tree=html.fromstring(jmeter_archive_get.text)
list_of_links=page_tree.xpath('//a[#href]/text()')
# Filter out all the non-md5s. There are a lot of links, and ultimately
# it's more data than needed for his exercise
jmeter_md5_list=list(filter(lambda x: x.endswith('.tgz.md5'), list_of_links))
# Here's where the 'magic' happens. We use two different regexes to rip the first
# and then the second number out of the string and turn them into integers. We
# then return them in the order we grabbed them, allowing us to tie break.
jmeter_md5_list.sort(key=lambda val: (int(re.search('(\d+)\.\d+', val).group(1)), int(re.search('\d+\.(\d+)', val).group(1))))
print(jmeter_md5_list)
This does have the desired effect, The output is:
['jakarta-jmeter-2.5.1.tgz.md5', 'apache-jmeter-2.6.tgz.md5', 'apache-jmeter-2.7.tgz.md5', 'apache-jmeter-2.8.tgz.md5', 'apache-jmeter-2.9.tgz.md5', 'apache-jmeter-2.10.tgz.md5', 'apache-jmeter-2.11.tgz.md5', 'apache-jmeter-2.12.tgz.md5', 'apache-jmeter-2.13.tgz.md5']
So we can see that the strings are sorted into an order that makes sense. Lowest version first and highest version last. Immediate problems that I see with my solution are two-fold.
First, we have to create two different regexes to get the numbers we want instead of just capturing groups 1 and 2. Mainly because I know there are no multiline lambdas, I don't know how to reuse a single regex object instead of creating a second.
Secondly, this only works as long as the version numbers are two numbers separated by a single period. The first element is 2.5.1, which is sorted into the correct place but the current method wouldn't know how to tie break for 2.5.2, or 2.5.3, or for any string with an arbitrary number of version points.
So it works, but there's got to be a better way to do it. How can I improve this?
This is not a full answer, but it will get you far along the road to one.
The return value of the key function can be a tuple, and tuples sort naturally. You want the output from the key function to be:
((2, 5, 1), 'jakarta-jmeter')
((2, 6), 'apache-jmeter')
etc.
Do note that this is a poor use case for a lambda regardless.
Originally, I came up with this:
jmeter_md5_list.sort(key=lambda val: list(map(int, re.compile('(\d+(?!$))').findall(val))))
However, based on Ignacio Vazquez-Abrams's answer, I made the following changes.
def sortable_key_from_string(value):
version_tuple = tuple(map(int, re.compile('(\d+(?!$))').findall(value)))
match = re.match('^(\D+)', value)
version_name = ''
if match:
version_name = match.group(1)
return (version_tuple, version_name)
and this:
jmeter_md5_list.sort(key = lambda val: sortable_key_from_string(val))
I am currently sorting values by key the following way
thrust::sort_by_key(thrust::device_ptr<int>(keys),
thrust::device_ptr<int>(keys + numKeys),
thrust::device_ptr<int>(values);
which sorts the "values" array according to "keys".
Is there a way to leave the the "values" array untouched and instead store the result of sorting "values" in a separate array?
Thanks in advance.
There isn't a direct way to do what you are asking. You have two options to functionally achieve the same thing.
The first is make a copy of the values array before the call, leaving you with a sorted and unsorted version of the original data. So your example becomes
thrust::device_vector<int> values_sorted(thrust::device_ptr<int>(values),
thrust::device_ptr<int>(values + numKeys));
thrust::sort_by_key(thrust::device_ptr<int>(keys),
thrust::device_ptr<int>(keys + numKeys),
values_sorted.begin());
The second alternative is not to pass the values array to the sort at all. Thrust has a very useful permutation iterator which allows for seamless permuted access to an array without modifying the order in which that array is stored (so an iterator based gather operation, if you will). To do this, create an index vector and sort that by key instead, then instantiate a permutation iterator with that sorted index, something like
typedef thrust::device_vector<int>::iterator iit;
thrust::device_vector<int> index(thrust::make_counting_iterator(int(0)),
thrust::make_counting_iterator(int(numKeys));
thrust::sort_by_key(thrust::device_ptr<int>(keys),
thrust::device_ptr<int>(keys + numKeys),
index.begin());
thrust::permutation_iterator<iit,iit> perm(thrust::device_ptr<int>(values),
index.begin());
Now perm will return values in the keys sorted order held by index without ever changing the order of the original data.
[standard disclaimer: all code written in browser, never compiled or tested. Use at own risk]