calculate exit rate in google datastudio - google-analytics

I'm trying to accomplish the following in either Google Analytics or Google datastudio:
I have a series of events which are allways triggered in identical order. The event category is the page that someone's on. Now I want to calculate the percentage of people that are left.
EA(event action)
EL(event label)
EA: A (100)
EA: B, EL: 1 (90, 90%)
EA: B, EL: 2 (80, 89%)
EA: B, EL: 3 (70, 87.5%)
EA: C (60, 86%)
If this isn't possible I would like to see it as a percentage of the total of step A which should be the same as pageviews. So then you'll get the following:
EA: A (100)
EA: B, EL: 1 (90, 90%)
EA: B, EL: 2 (80, 80%)
EA: B, EL: 3 (70, 70%)
EA: C (60, 60%)
I've searched a lot for something in datastudio or analytics that could get me on my way but I'm really lost here. There has to be someone out there that knows how to achieve this or tell me that I'm doing it all wrong.

Percentage of total is now supported in Data Studio using Analytics Functions.

Related

Initialization of Arcs depening on Sets/Subsets in directed graphs in CPLEX

I am dealing with a directed weighted graph and have a question about how to initialize a set a defined in the following:
Assume that the graph has the following nodes, which are subdivided into three different subsets.
//Subsets of Nodes
{int} Subset1= {44,99};
{int} Subset2={123456,123457,123458};
{int} Subset3={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
{int} Nodes=Subset1 union Subset2 union Subset3;
Now there is a set of H_j arcs, where j is in Nodes. H_j gives all arcs outgoing from Node j.
The arcs are stored in an excel file with the following structure:enter image description here
For node 44 in Nodes (Subset 1), there are the arcs <44,123456>, <44,123457>, <44,123458>. For 66 in Nodes (Subset 2), there is no arc. Can somebody help me how to implement this?
Important is that the code uses the input from the excel because in my real case there will be too much data to make a manual input... :(
Maybe there is a real easy solution for that. I would be very thankful!
Thank you so much in advance!
enter image description here
This addition refers to the answer from #Alex Fleischer:
Your code seems to work also in the overall context.
I am trying to implement the following constraints within a Maximization optimization ( The formulations (j,99) and (j,i) in the lower sum boundaries represent arcs):
enter image description here
I tried to implement it like this:
{int} TEST= {99};
subject to {
sum(m in M, j in a[m])x[<44,j>]==3;
sum(j in destPerOrig[99], t in TEST)x[<j,t>]==3;
forall(i in Nodes_wo_Subset1)
sum(j in destPerOrig[i],i in destPerOrig[i])x[<j,i>]==1;
}
M is a set of trains and a[M] gives a specific cost value for each indiviudal train. CPLEX shows 33 failure messages.
The most frequent one is that it cannot extract x[<j,i>], sum(in in destPerOrig[i]), sum(j in destPerOrig[i] and that x and destPerOrig are outside of the valid area.
Most probably the problem is that I implement the constraints in the wrong manner. Again, it is a directed graph.
Referring to the mathematical formulation in the screenshot: Could the format of destPerOrig[i] be a problem?
At the moment destPerOrig[44] gives {2 3 4}. But should´t it give:
{<44 2> <44 3> <44 4>} to work within the mathematical formulation?
I hope that this is enoug information for you to help me :(
I would be very thankful!
all arcs outgoing from Node j.
How to do this depends on how you store the adjacencies of the graph.
Perhaps you store a vector of arcs:
LOOP over arcs
IF arc source == node J
ADD to output
.mod
tuple arcE
{
string o;
string d;
}
{arcE} arcsInExcel=...;
{int} orig={ intValue(a.o) | a in arcsInExcel};
{int} destPerOrig[o in orig]={intValue(a.d) | a in arcsInExcel : intValue(a.o)==o && a.d!="" };
execute
{
writeln(orig);
writeln("==>");
writeln(destPerOrig);
}
/*
which gives
{44 66}
==>
[{2 3 4} {}]
*/
https://github.com/AlexFleischerParis/oplexcel/blob/main/readarcs.mod
.dat
SheetConnection s("readarcs.xlsx");
arcsInExcel from SheetRead(s,"A2:B5");
https://github.com/AlexFleischerParis/oplexcel/blob/main/readarcs.dat

How to multiply matrix by a view with ndarray?

Using ndarray. This playground snippet says it all -- I want to multiply a matrix view element-wise with a matrix, and I can't figure out a combination of views and casts and whatnot that'll make it work.
#![allow(unused)]
use ndarray::{Array1, Array2, Axis};
fn main () {
let bob = Array1::from(vec![1.2, 3.3, 4.]);
let ralph = Array2::from(vec![[3.3, 1.0, -2.0],[4., 5., 8.], [-9., 2., 1.]]);
println!("{:?}", ralph.index_axis(Axis(1), 0) * bob);
}
On compilation gives the error:
error[E0369]: cannot multiply `ArrayBase<ViewRepr<&{float}>, Dim<[usize; 1]>>` by `ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>`
--> src/lib.rs:8:51
|
8 | println!("{:?}", ralph.index_axis(Axis(1), 0) * bob);
| ---------------------------- ^ --- ArrayBase<OwnedRepr<{float}>, Dim<[usize; 1]>>
| |
| ArrayBase<ViewRepr<&{float}>, Dim<[usize; 1]>>
Is there a magic finger-ring combination that'll make it do what I want, or do I need to do it by hand?
Adding a & to both elements of the multiplication will prevent either value from being consumed in the process of multiplication:
&ralph.index_axis(Axis(1), 0) * &bob
The following link from the ndarray docs explains allocating a new array vs consuming the array during binary operations: https://docs.rs/ndarray/0.14.0/ndarray/struct.ArrayBase.html#binary-operators-with-two-arrays
I think because the result of index_axis() is a view into another array, it can't be consumed safely, hence the error
Swapping the order of the operations also fixes it:
#![allow(unused)]
use ndarray::{Array1, Array2, Axis};
fn main () {
let bob = Array1::from(vec![1.2, 3.3, 4.]);
let ralph = Array2::from(vec![[3.3, 1.0, -2.0],[4., 5., 8.], [-9., 2., 1.]]);
println!("{:?}", bob * ralph.index_axis(Axis(1), 0));
}

recursion in NetLogo

In NetLogo 6.1.1 I have one breed (rangers) looking for another breed (snares) in green patches (bush).
The behaviour that I can't get is this:
if a snare is found, remove the snare with 80% success rate; then
repeat the same procedure (hotspot-search; recursive call).
if the snare is not found (20% probability) then repeat the same
procedure (hotspot-search; the commented out section -> causes an endless loop) 5 times.
if no snares are removed in these 5 times, resume normal behaviour (move by random right turn and forward 1).
How can I do this?
;; globals =========================
breed [rangers ranger]
breed [snares snare]
rangers-own [snare-found?]
;; initialise ========================
to setup
resize-world -4 4 -4 4
clear-all
create-rangers 1 [set color blue]
ask patches [
if random 100 < 20 [set pcolor green]]
ask patches with [pcolor = green] [
sprout-snares random 5]
ask snares [
set size 0.5
set shape "dot"
fd 0.25
]
reset-ticks
end
;; main ==================================
to go
ask rangers [
rt random 181 - 90
fd 1
if any? snares-here [hotspot-search]
hotspot-search
]
end
;; functions ===============================
to hotspot-search
move-to patch-here
let target one-of snares-here
if (random 100 < 20) and (target != nobody) [
ask target [die]
set snare-found? true
hotspot-search
]
;;if snare-found? = true [
;; repeat 5 [hotspot-search]
;;]
end
One observation I'd make is that if you're wanting the rangers to search 5 times at a 20% chance of success, but there is no cost for searching, like lost time or energy, you can just do a single check at a 67% chance of success (1.00 - 0.80^5) = 0.67.
But if you do need have a cost or need to track the number of searches or something like that, below is how I'd write the code. Sorry for writing from scratch rather than updating yours, I was just trying to keep things as simple as possible.
breed [ rangers ranger ]
breed [ snares snare ]
to setup
create-snares 100 [
set shape "circle"
set color blue
set size 0.5
move-to one-of patches
]
create-rangers 10 [
set color red
move-to one-of patches
]
end
to go
ask rangers [
move-to one-of neighbors4
; call our procedure with the starting limit of 5
hunt-snares 5
]
end
to hunt-snares [ search-limit ]
; the recursive base case is search-limit of 0
if ( search-limit > 0 ) [
; can only find a snare if one exists here
ifelse random 100 < 20 and any? snares-here [
; found one
ifelse random 100 < 80 [
; disabled
ask one-of snares-here [ die ]
; restart the search
hunt-snares 5
] [
; we found a snare but failed to disable it, unclear what to do?
hunt-snares 5
]
] [
; failed to find one, move towards the base case
hunt-snares (search-limit - 1)
]
]
end
Edit to add: Sorry, I thought your original code was more complicated, it actually looks relatively simple and I probably should've just modified your version. The reason your hotspot-search procedure is going into an infinite loop is because snare-found? is never set to false anywhere in your code. The typical way to handle recursion is to have one parameter of the recursive procedure progress towards a base case where the last recursive call can quit and the whole chain of calls will end, too.
In this case we have two complications: 1) an implicit base-case that isn't a parameter - that there are still snares on the patch to try to disarm, and 2) that we can reset our parameter farther from the base case, knowing that item 1 means we won't loop over.

Can someone explain this code that recursively finds the minimum element in an array in C?

I don't quite understand this piece of code. So if for example n = 5 and we have:
array[5] = {13, 27, 78, 42, 69}
Would someone explain please?
All I understand is if n = 1, that is the lowest.
But when n = 5, we would get the 4th index and compare it to the 4th index and check which is the smallest and return the smallest, then take the 4th index and compare it to the 3rd index and check which one is the smallest and return the smallest? I am confused.
int min(int a, int b)
{
return (a < b) ? a: b;
}
// Recursively find the minimum element in an array, n is the length of the
// array, which you assume is at least 1.
int find_min(int *array, int n)
{
if(n == 1)
return array[0];
return min(array[n - 1], find_min(array, n - 1));
}
Given your array:
1. initial call: find_min(array, 5)
n!=1, therefore if() doesn't trigger
2. return(min(array[4], find_min(array, 4)))
n!=1, therefore if doesn't trigger
3. return(min(array[3], find_min(array,3)))
n!=1, therefore if doesn't trigger
4. return(min(array[2], find_min(array,2)))
n!=1, threfore if() doesn't trigger
5. return(min(array[1], find_min(array,1)))
n==1, so return array[0]
4. return(min(array[1], array[0]))
return(min(13, 27)
return(13)
3. return(min(array[2], 13))
etc...
It's quite simple. Run through the code using the example you gave.
On the first run through find_min(), it will return the minimum of the last element in the array (69) and the minimum of the rest of the array. To calculate the minimum of the rest of the array, it calls itself, i.e. it is recursive. This 2nd-level call will compare the number 42 (the new "last" element) with the minimum from the rest of the array, and so on. The final call to find_min() will have n=1 with the array "{13}", so it will return 13. The layer that called it will compare 13 with 27 and find that 13 is less so it will return it, and so on back up the chain.
Note: I assume the backward quotes in your code are not supposed to be there.
The solution uses recursion to compute the minimum for the smallest possible comparison set and comparing that result with the next bigger set of numbers. Each recursive call returns a result that is compared against the next element in a backward manner until the minimum value bubbles up to the top. Recursion appears to be tricky at first, but can be quite effective once you get familiar with it.

Doubts with transitive closure in Alloy

I am doing a model in Alloy to represent a subset of Java language. Below we have some elements of this model:
sig Method {
id : one MethodId,
param: lone Type,
return: one Type,
acc: lone Accessibility,
b: one Block
}
abstract sig Expression {}
abstract sig StatementExpression extends Expression {}
sig MethodInvocation extends StatementExpression{
pExp: lone PrimaryExpression,
id_methodInvoked: one Method,
param: lone Type
}
sig Block {
statements: set StatementExpression
}
pred noRecursiveMethodInvocationCall [] {
all bl:Block | all mi, mi2: MethodInvocation | all m:Method |
bl in m.b && mi in bl.statements
&& mi2 = mi.*(id_methodInvoked.b.statements) =>
m != mi2.id_methodInvoked
}
The problem is that the predicate noRecursiveMethodInvocationCall apparently is not working since the instances generated contains methods being invoked in a recursive way (even indirectly, e.g. m1 invokes m2, that invokes m3 that in turn invokes m1) and i want to avoid recursion.
The instances are generated through another model, see below:
open javametamodel_withfield_final
one sig BRight, CRight, BLeft, CLeft, Test extends Class{
}
one sig F extends Field{}
fact{
BRight in CRight.extend
BLeft in CLeft.extend
F in BRight.fields
F in CLeft.fields
all c:{Class-BRight-CLeft} | F !in c.fields
}
pred law6RightToLeft[]{
proviso[]
}
pred proviso [] {
some BRight.extend
some BLeft.extend
#(extend.BRight) > 2
#(extend.BLeft) > 2
no cfi:FieldAccess | ( cfi.pExp.id_cf in extend.BRight || cfi.pExp.id_cf in BRight || cfi.pExp.id_cf in extend.BLeft || cfi.pExp.id_cf in BLeft) && cfi.id_fieldInvoked=F
some Method
}
run law6RightToLeft for 9 but 15 Id, 15 Type, 15 Class
Please, does anyone have any clue what the problem is?
Thanks in advance for the attention,
Follow-on query
Still regarding this question, the predicate suggested solves the recursion problem:
pred noRecursiveMethodInvocationCall [] {
no m:Method
| m in m.^(b.statements.id_methodInvoked)
}
However, it causes inconsistency with another predicate (see below), and instances are not generated when both predicates exist.
pred atLeastOneMethodInvocNonVoidMethods [] {
all m:Method
| some mi:MethodInvocation
| mi in (m.b).statements
}
Any idea why instances can not be generated with both predicates?
You might look closely at the condition
mi2 = mi.*(id_methodInvoked.b.statements)
which seems to check whether the set of all statements reachable recursively from mi is equal to the single statement mi2. Now, unless I've confused myself about multiplicities again, mi2 is a scalar, so in any case where the method in question has a block with more than one method-invocation statement, this condition won't fire and the predicate will be vacuously true.
Changing = to in may be the simplest fix, but in that case I expect you won't get any non-empty instances, because you're using * and getting reflexive transitive closure, and not ^ (positive transitive closure).
It looks at first glance as if the condition might be simplified to something like
pred noRecursion {
no m : Method
| m in m.^(b.statements.idMethodInvoked)
}
but perhaps I'm missing something.
Postscript: a later addition to the question asks why no instances are generated when the prohibition on recursion is combined with a requirement that every method contain at least one method invocation:
pred atLeastOneMethodInvocNonVoidMethods [] {
all m:Method
| some mi:MethodInvocation
| mi in (m.b).statements
}
Perhaps the simplest way to see what's wrong is to imagine constructing a call graph. The nodes of the graph are methods, and the arcs of the graph are method invocations. There is an arc from node M1 to node M2 if the body of method M1 contains an invocation of method M2.
If we interpret the two predicates in terms of the graph, the predicate noRecursiveMethodInvocationCall means that the graph is acyclic. The predicate atLeastOneMethodInvocNonVoidMethods means that every node in the graph has at least one outgoing arc.
Try it with a single method M. This method must contain a method invocation, and this method invocation must invoke M (since there is no other method in the universe). So we have an arc from M to M, and the graph has a cycle. But the graph is not allowed to have a cycle. So we cannot create a one-method universe that satisfies both predicates.
Try again with two methods, M1 and M2. Let M1 call M2. Now, what does M2 call? It can't call M1 without making a cycle. It can't call M2 without making a cycle. Again we fail.
I don't have the time just now to look it up, but I think you'll find there is a basic theorem of graph theory that if the number of edges equals the number of nodes, the graph must have a cycle.

Resources