What do these asterisks and dots mean in SAS code? - sas

I am trying to understand the following SAS code snippet:
SUM( (list=.)*. , (list=.B)*. , (list=.D)*. , (list=.Q)*. )
where list contains several elements. My understanding so far is that SUM will create a new list as an output of the same length as list, summing the respective elements in the four entries. I guess list=. or list=.B etc maps the elements of list to 1 where the equality is satisfied and to 0 where it is not, but what does it mean for an element to be equal to a dot .? And what kind of quantity can .B be? Also, what does it mean to multiply by a dot, as in variable * .?
EDIT:
Upon further investigation I found out that "." stands for a NaN numeric value in SAS, so I guess list=. produces a new list where all NaN elements in list are set to 1, and all regular numbers are set to 0. But what does it mean to then multiply the resulting new list by .? And what could .B be?

What you posted kind of looks like SAS code, but not sensible SAS code.
SUM(...) in that code is a function call. The function that can take one or more arguments.
= in that code is the equality comparison operator.
* in the code is the multiplication operator.
. and .B and .D and .Q are missing values. The first is the normal missing values and the other three are examples of the other 27 special missing values that SAS supports.
Normal arithmetic, such as X+Y or A*B, will produce a missing result if any of the arguments are missing. But the SUM(,) function ignores the missing values. So the result is only missing if all of the arguments are missing.
The result of a boolean expression, such as LIST=.D , is either 1 (TRUE) or 0 (FALSE). Note that SAS only uses actual Boolean logic, it does not use the Tri-level logic that some other languages use. So X=. is true when the value of X is missing and false when it is not missing (including any of the 27 special missing values).
So far the code begins to look like an attempt to test if LIST is any of those missing values. So something like:
SUM( (list=.) , (list=.B) , (list=.D) , (list=.Q) )
This will be 1 when LIST is any of those four values. And 0 when none of the test is true.
So it is the same test as using the IN operator. Like this
list in (. .B .D .Q)
But by adding the multiplication by a missing value is what makes it nonsense. Because that will always result in a missing result. So you could just replaced the whole SUM() function call with a period to indicate you wanted a missing value no matter what value LIST had.
If you substitute actual numbers for those missing multiplicand values.
SUM( (list=.)*1 , (list=.B)*2 , (list=.D)*3 , (list=.Q)*4 )
Then perhaps it might make some sense. Now the result is a value that is coded 1 when LIST is missing and 2 when LIST is special missing .B, 3 when .D, 4 when .Q and zero otherwise.

Related

Airtable If-statement outputting NaN

I'm using an If-statement to assign integers to strings from another cell. This seems to be working, but if I reference these columns, I'm getting a NaN value. This is my formula below. I tried adding INT() around the output values, but that seemed to break everything. Am I missing something?
IF(FIND('1',{Functional response}),-4,
IF(FIND('2',{Functional response}),-2,
IF(FIND('3',{Functional response}),0,
IF(FIND('4',{Functional response}),2,
IF(FIND('5',{Functional response}),4,"")))))
Assuming Functional response can only store a number 1 to 5 as a string a simple option in excel would be to first convert the string to a number and then use the choose function to assign a value. this works as the numbers are are sequential integers. Assuming Cell K2 has the value of Functional response, your formula could be:
=CHOOSE(--K2,-4,-2,0,2,4)
=CHOOSE(K2+0,-4,-2,0,2,4)
=CHOOSE(K2-0,-4,-2,0,2,4)
=CHOOSE(K2*1,-4,-2,0,2,4)
=CHOOSE(K2/1,-4,-2,0,2,4)
Basically sending the string of a pure number through a math operation has excel convert it to a number. By sending it through a math operation that does not change its value, you get the string as a number.
CHOOSE is like a sequential IF function Supply it with an integer as the first argument and then it will return the value from the subsequent list that matches the number. if the number you supply is greater than the number of options you will get an error.
Alternatively you could just do a straight math convertion on the number stored as a string in K2 using the following formula:
=(K2-3)*2
And as my final option, you could build a table and use VLOOKUP or INDEX/MATCH.
NOTE: If B2:B6 was stored as strings instead of numbers, K2 instead of --K2 would need to be used.

Best way to show blank cell if value if zero

=COUNTIFS(Orders!$T:$T,$B4)
is a code that gives 0 or a +ve result
I use this across 1500 cells which makes the sheet gets filled with 0s
I'd like to remove the Zeros by using the following formula
if(COUNTIFS(Orders!$T:$T,$B3,Orders!$F:$F,""&P$1&"*")=0,
"",
COUNTIFS(Orders!$T:$T,$B3,Orders!$F:$F,""&P$1&"*"))
This calculates every formula twice and increases the calculation time.
How can we do this in 1 formula where if the value is 0 - keep empty - otherwise display the answer
I suggest this cell-function:
=IFERROR(1/(1/COUNTIFS(Orders!$T:$T,$B4)))
EDIT:
I'm not sure what to add as explanation. Basically to replace the result of a complex calculation with blank cells if it results in 0, you can wrap the complex function in
IFERROR(1/(1/ ComplexFunction() ))
It works by twice taking the inverse (1/X) of the result, thus returning the original result in all cases except 0 where a DIV0 error is generated. This error is then caught by IFERROR to result in a blank cell.
The advantage of this method is that it doesn't need to calculate the complex function twice, so can give a significant speed/readability increase, and doesn't fool the output like a custom number format which can be important if this cell is used in further functions.
You only need to set the number format for your range of cells.
Go to the menu Format-->Number-->More Formats-->Custom Number Format...
In the entry area at the top, enter the following: #;-#;""
The "format" of the format string is
(positive value format) ; (negative value format) ; (zero value format)
You can apply colors or commas or anything else. See this link for details
instead of your =COUNTIFS(Orders!$T:$T,$B4) use:
=REGEXREPLACE(""&COUNTIFS(Orders!$T:$T,$B4), "^0$", )
also, to speed up things you should avoid "per row formulae" and use ArrayFormulas

If Statement giving value error

I am trying to compare two data ranges to determine if they are the same or not.
I'm using the following statement and I get a #Value! error message:
=IF(SUM(ABS(B2:E7-G2:J7))=0,"Same", "Not")
If you are looking to see if the arithmetic total of the numbers in the two ranges is the same then this standard formula should do.
=IF(SUM(B2:E7)-SUM(G2:J7), "Not", "Same")
A zero in Excel evaluates to a boolean FALSE. Anything that is not false is TRUE.
This does not determine whether each cell directly corresponds to its 'sister' cell in the other range; only that the sum total of each is equal or not. The values in different cells could be interchanged or by coincidence be offset from one another in a perfect proportion to create an equal sum.
If you require a cell by cell analysis, then a much more complicated formula could be provided.
=IF(SUMPRODUCT(--(B2:E7=G2:J7))=24, "Same", "Not")
24 being the total number of cells in each range. While this does not require Ctrl+Shift+Enter, a SUMPRODUCT function does produce cyclic calculations.
Do you have strings in your answer or have the formula in row 1 or 8+? If yes that might be the reason as the formula works correctly assuming you
hit ctrl+shift+enter and
have only numbers in the ranges
For a general solution try
{=IF(AND(B2:E7=G2:J7),"Same","Not")}
Do not forget to hit ctrl+shift+enter as otherwise it will only look at the row the formula itself is in!

Avoid converting numbers to characters in Erlang

I am having trouble with Erlang converting listed numbers to characters whenever none of the listed items could not also be representing a character.
I am writing a function to separate all the numbers in a positive integer and put them in a list, for example: digitize(123) should return [1,2,3] and so on.
The following code works fine, except when the list only consist of 8's and/or 9's:
digitize(_N) when _N =:= 0 -> [];
digitize(_N) when _N > 0 -> _H = [_N rem 10], _T = digitize(_N div 10), _T ++ _H.
For example: Instead of digitize(8) returning [8], it gives me the nongraphic character "\b" and digitize(89) returns "\b\t". This is only for numbers 8 and 9 and when they're put alone inside the list. digitize(891) will correctly return [8,9,1] for example.
I am aware of the reason for this but how can I solve it without altering my result? (ex: to contain empty lists inside the result like [[],[8]] for digitize(8)).
If you look at comments you will see that it is more problem of the way shell prints your data, than the data itself. You logic is wright and I would not change it. You could introduce some use of io:format/2 into you code, but I guess that it would make it harder to use this function in other parts of code.
Other way around it is changing the shell settings itself. There is shell:strings/1 functions that disables printing lists as stings, and it should do exactly what you want. Just remember to change it back when you finish with your shell stuff, since it could introduce some confusion when you will start using some "string" returning functions.

Update vlookup table array

Suppose I have the following vlookup command:
=VLOOKUP('Sheet1'!S2,'Sheet2'!$B$138:$C$145,2,FALSE)
When I drag the vlookup to the right I want it to update to
=VLOOKUP('Sheet1'!S2,'Sheet2'!$B$146:$C$153,2,FALSE)
In other words, I want the letters B and C fixed but the numbers to increment by 8. How would I do this?
It looks like your answer is always in column C and your lookup value in column A. If this is the case use INDEX MATCH
=INDEX ( C:C , MATCH ( 'Sheet1'!S2 , 'Sheet2'!$B:$C , 0 ))
I've made a few assumptions. Drop a pic of your tables and I can amend it if you can't work out which bits to change
That may be possible using some long if-then-else logic or macro but it seems an odd thing to do. The numbers represent rows so if you are incrementing them across columns I wonder whether you need to transpose your data and/or use HLOOKUP instead. There is probably a better way to achieve what you want but it is difficult to answer from the question as provided.