I am trying to calculate an amount based on a formula that has a different number of arguments for each calculation. And, each formula is expressed as a string that is based on the column names at the top of the sheet (e.g. item1). Each argument feeds a XLOOKUP to get the value and then that value gets added to the one before it (a+b+c+d).
|item1|item2|item3|item4|item5|
itemAmount 100 50 25 2 3
rate ? ? ? ? ?
formula for item1 rate = item1
formula for item2 rate = item1, item2
formula for item3 rate = item3
formula for item4 rate = item3, item4
formulas are expressed in a comma-separated array in a cell in the worksheet.
Desired Results:
rate for item1 = 100
rate for item2 = 150
rate for item3 = 25
rate for item4 = 27
rate for item5 = 180
The below works until I have 4 or more arguments to add together.
e.g. item1, item2, item3, item4 will not get calculated.
Is there a way to implement this that truly loops through the formula arrays?
I tried REDUCE() but that didn't seem to recognize text.
What I have so far is a combination of LAMBDA() and LET().
I used LAMBDA() to create a reusable formula for the users that will get inserted in dozens of places in the workbook.
=LAMBDA(
TaskFormula,TaskNamesRange,RateName,RateNamesRange,ReturnRange,
LET(
tfl,
TaskFormula,
tnrng,
TaskNamesRange,
rateType,
TRIM(RIGHT(RateName,LEN(RateName)-FIND(">> ",RateName)-1)),
rateNameRng,
RateNamesRange,
retRng,
ReturnRange,
a,
XLOOKUP(IFERROR(TRIM(LEFT(tfl,FIND(", ",tfl)-1)),tfl),tnrng,XLOOKUP(rateType,rateNameRng,retRng)),
b,
IFERROR(XLOOKUP(TRIM(SUBSTITUTE(MID(SUBSTITUTE(","&tfl&REPT(" ",6),",",REPT(",",255)),2*255,255),",","")),tnrng,XLOOKUP(rateType,rateNameRng,retRng)),0),
c,
IFERROR(XLOOKUP(TRIM(MID(tfl,FIND("#",SUBSTITUTE(tfl,",","#",2))+1,255)),tnrng,XLOOKUP(rateType,rateNameRng,retRng)),0),
a+b+c))
Prefer no VBA if possible.
Using Win10, Excel 365 Monthly Enterprise channel.
Use SUMIFS with TEXTSPLIT:
=LAMBDA(TaskFormula,TaskNamesRange,ReturnRange,SUM(SUMIFS(ReturnRange,TaskNamesRange,TEXTSPLIT(TaskFormula,", "))))
TEXTSPLIT may not currently be available to all. In that case use FILTERXML in its place:
=LAMBDA(TaskFormula,TaskNamesRange,ReturnRange,SUM(SUMIFS(ReturnRange,TaskNamesRange,FILTERXML("<t><s>"&SUBSTITUTE(TaskFormula,",","</s><s>")&"</s></t>","//s"))))
Or this one that does not split the formula but looks to see if the item is included in the formula:
=LAMBDA(TaskFormula,TaskNamesRange,ReturnRange,SUM(BYCOL(SEQUENCE(,COLUMNS(TaskNamesRange),1,1),LAMBDA(a,IF(ISNUMBER(SEARCH(INDEX(TaskNamesRange,,a),TaskFormula)),INDEX(ReturnRange,,a),0)))))
I want to build an iteration using the Stata FAQ here. The second method seems fitting for my case. I have built the following code:
levelsof ID, local(levels)
foreach l of local levels {
var var1 var2 if ID == `l', lags(1/4) vsquish
vargranger
}
Idea: iterate over all IDs in ID, then do vargranger. However, it runs once, then outputs no observations. Which is not true, as I have 200 IDs in my search variable.
Second thing I want to add into my loop, a return / print function of the current ID used in ID.
The output should look like this, for each value of ID:
ID = XYZ
Sample: 2001 - 2019 Number of obs = 16
...
vargranger
Granger causality Wald tests
+------------------------------------------------------------------+
| Equation Excluded | chi2 df Prob > chi2 |
|--------------------------------------+---------------------------|
| var1 var2 | 11.617 4 0.020 |
| var1 ALL | 11.617 4 0.020 |
|--------------------------------------+---------------------------|
| var2 var1 | 6.2796 4 0.179 |
| var2 ALL | 6.2796 4 0.179 |
+------------------------------------------------------------------+
display of the current level is easy enough, say:
levelsof ID, local(levels)
foreach l of local levels {
di "{title:`l'}" _n
count if !missing(var1, var2) & ID == `l'
var var1 var2 if ID == `l', lags(1/4) vsquish
vargranger
}
The report "no observations" is presumably coming from var and is not a reflection of how many identifiers you have. You should add checks like that above for (e.g.) how many observations you have to play with.
I have a dataset as such:
Case #|DateA |Drug.1|Drug.2|Drug.3|DateB.1 |DateB.2 |DateB.3 |IV.1|IV.2|IV.3
------|------|------|------|------|--------|---------|--------|----|----|----
1 |DateA1| X | Y | X |DateB1.1|DateB1.2 |DateB1.3| 1 | 0 | 1
2 |DateA2| X | Y | X |DateB2.1|DateB2.2 |DateB2.3| 1 | 0 | 1
3 |DateA3| Y | Z | X |DateB3.1|DateB3.2 |DateB3.3| 0 | 0 | 1
4 |DateA4| Z | Z | Z |DateB4.1|DateB4.2 |DateB4.3| 0 | 0 | 0
For each case, there are linked variables i.e. Drug.1 is linked with DateB.1 and IV.1 (Indicator Variable.1); Drug.2 is linked with DateB.2 and IV.2, etc.
The variable IV.1 only = 1 if Drug.1 is the case that I want to analyze (in this example, I want to analyze each receipt of Drug "X"), and so on for the other IV variables. Otherwise, IV = 0 if the drug for that scenario is not "X".
I want to calculate the difference between DateA and DateB for each instance where Drug "X" is received.
e.g. In the example above I want to calculate a new variable:
DateDiffA1_B1.1 = DateA1 - DateB1.1
DateDiffA1_B2.1 = DateA1 - DateB2.1
DateDiffA1_B1.3 = DateA1 - DateB1.3
DateDiffA1_B2.3 = DateA1 - DateB2.3
DateDiffA1_B3.3 = DateA1 - DateB3.3
I'm not sure if this new variable would need to be linked to each instance of Drug "X" as for the other variables, or if it could be a single variable that COUNTS all the instances for each case.
The end goal is to COUNT how many times each case had a date difference of <= 2 weeks when they received Drug "X". If they did not receive Drug "X", I do not want to COUNT the date difference.
I will eventually want to compare those who did receive Drug "X" with a date difference <= 2 weeks to those who did not, so having another indicator variable to help separate out these specific patients would be beneficial.
I am unsure about the best way to go about this; I suspect it will require a combination of IF and REPEAT functions using the IV variable, but I am relatively new with SPSS and syntax and am not sure how this should be coded to avoid errors.
Thanks for your help!
EDIT: It seems like I may need to use IV as a vector variable to loop through the linked variables in each case. I've tried the syntax below to no avail:
DATASET ACTIVATE DataSet1.
vector IV = IV.1 to IV.3.
loop #i = .1 to .3.
do repeat DateB = DateB.1 to DateB.3
/ DrugDateDiff = DateDiff.1 to DateDiff.3.
if IV(#i) = 1
/ DrugDateDiff = datediff(DateA, DateB, "days").
end repeat.
end loop.
execute.
Actually there is no need to add the vector and the loop, all you need can be done within one DO REPEAT:
compute N2W=0.
do repeat DateB = DateB.1 to DateB.3 /IV=IV.1 to IV.3 .
if IV=1 and datediff(DateA, DateB, "days")<=14 N2W = N2W + 1.
end repeat.
execute.
This syntax will first put a zero in the count variable N2W. Then it will loop through all the dates, and only if the matching IV is 1, the syntax will compare them to dateA, and add 1 to the count if the difference is <=2 weeks.
if you prefer to keep the count variable as missing when none of the IV are 1, instead of compute N2W=0. start the syntax with:
If any(1, IV.1 to IV.3) N2W=0.
Here is my sample List ,
$scope.list_element = [1,2,3,4,5,6,7,8,9,10];
I want to Iterate this List into Multiple Rows, each Row should contain 2 elements from the List.
required output,
1 , 2
3 , 4
5 , 6
7 , 8
9 , 10
i am getting like this,
1
2
3
4
5
6
7
8
9
10
I tried this using ng-repeat i.e: ng-repeat="val in list_element"
<div ng-repeat="val in list_element">
<p>{{val}}</p>
</div>
i know this is wrong.. it will give one by one... but i want to iterate 2 values in a row instead one...
The problem is the <p> tag will create a new line by default each time you execute it. And if you replaced it with anything else such as or just text inside a div
<div ng-repeat="val in list_element">
{{ val }}
</div>
this will output 12345678910
In order to solve it, you can use the special $odd or $even like this
<div ng-repeat="val in list_element tracked by $index">
<br ng-if="$odd"/>{{ val }}
</div>
notice that the <br/> will only add a new line to output when it's odd. Adjust it to get the result you are seeking.
I have a matrix defined in my report which looks similar to this:
I want to add another row that is the Total value from Row 5 divided by the Total value from Row 1
As these rows are produced dynamically how can I do this?
The first column is grouped and the Total column is a SUM. I need to pick out the Total values based on the grouping column and divide the two.
Are the values of Row 1 and Row 5 constant, or will the row numbers you are calculating on always be 1 and 5?
You could use custom code to store the values in variables and then perform the calculation using those.
Create a function which takes both Col1 value and the calculated value of Col2. It will then assign Row1 to var1 and Row5 to var2. It will then return the value of Col2 for display as the Total value.
Make sense? Let me know if you need some help with the function...
EDIT
SSRS:
Col 1 | Col 2 | Col 2 Expression
England | 201 | =Code.SetOneFive(Count(Fields!Country.Value))
Ireland | 451 | =Code.SetOneFive(Count(Fields!Country.Value))
Scotland | 215 | =Code.SetOneFive(Count(Fields!Country.Value))
Wales | 487 | =Code.SetOneFive(Count(Fields!Country.Value))
Zenovia | 2145 | =Code.SetOneFive(Count(Fields!Country.Value))
Code:
Public Shared Dim i as Integer = 1
Public Shared Dim rowOne as Integer
Public Shared Dim rowFive as Integer
Public Function SetOneFive (byval _OneFive As Integer) as Integer
If i = 1 then
rowOne = _OneFive
Else If i = 5 then
rowFive = _Onefive
End If
i = i + 1
End Function
Public Function GetRowOne () As Integer
GetRowOne = RowOne
End Function
Public Function GetRowFive () As Integer
GetRowFive = RowFive
End Function
For every iteration of the code, i is increased by 1. This is checked every iteration for a value of 1 or 5.
In your total column you can then use:
=Code.GetRowFive() / Code.GetRowOne()
Note: I haven't tested this so there could be some typos or syntactical errors, but you get the general idea.
Depending on how you use this you may want to consider not declaring the variables as 'shared':
SSRS code variable resetting on new page