I've been looking around for this for a couple days but haven't found exactly what I need so here we go:
Cell C2 is a date, cell G2 is a dollar amount.
If/When C2 is one-year-old I need G2 to turn red.
Ex.)
C2 = 6/1/2018, G2 = $250 in red
or
C3 = 2/1/2021, G3 = $250 in black (but will turn red on 2/2/2022)
thoughts?
Try this:
Create Conditional Formatting for G2 (New Rule -> Use a formula to determine which cells to format) and use this formula:
=DATEDIF(C2,TODAY(),"Y")>0
Rest of the formatting like color border etc. set as you like.
Edit:
I realised that this will put G2 in red on the same day next year. For example:
C3 = 2/1/2021, G3 = $250 in black (but will turn red on 2/1/2022)
If you need it next day just modify formula to this:
=DATEDIF(C2,TODAY()-1,"Y")>0
Related
I am learning the networkx function named "networkx.graph_edit_distance(g2,q)". Actually, GED(g2,q) = 2.If we want to tranform g2 to q, we should do at least 2 graph edit operations"substituing (1,3) whose label is '2' in g2 to (1,3) whose label is '1', inserting (3,4) which is not exsits in g2 to (3,4) whose label
is '1".My code is shown below:
nodes = [(1,{'label':'C1'}),
(2,{'label':'C2'}),
(3,{'label':'C3'}),
(4,{'label':'C4'}),
(5,{'label':'N'})]
edges = [(1,2,{'label':'1'}),
(2,4,{'label':'1'}),
(4,5,{'label':'1'}),
(5,3,{'label':'1'}),
(3,1,{'label':'2'})]
g2 = nx.Graph()
g2.add_nodes_from(nodes)
g2.add_edges_from(edges)
nodes = [(1,{'label':'C1'}),
(2,{'label':'C2'}),
(3,{'label':'C3'}),
(4,{'label':'C4'}),
(5,{'label':'N'})]
edges = [(1,2,{'label':'1'}),
(2,4,{'label':'1'}),
(4,5,{'label':'1'}),
(5,3,{'label':'1'}),
(3,1,{'label':'1'}),
(3,4,{'label':'1'})]
q = nx.Graph()
q.add_nodes_from(nodes)
q.add_edges_from(edges)
GED_q_g2 = nx.graph_edit_distance(g2, q)
But unfortunately, the expected answer is GED =2, but it gives the answer GED_q_g2 = 1.Please how could I get the right answer?
When I look at the defined graph, the edit distance of 1 is correct, because only (3,4) needs to be removed.
The graph that you've drawn displays two edges between 1 and 3, though. I guess you've misunderstood the label functionality: It's just an optional data attribute that you can use for identification or plotting - it has nothing to do with the number of edges or weights.
If you want to use multiple edges between two nodes, have a look at nx.Multigraph.
just use the edge_match.
nx.graph_edit_distance(g1,g2,edge_match=lambda a,b: a['label'] == b['label']))
% S
a1 = [2015/07/23 2015/11/25 2016/01/20];
b1 = [2011/06/22 2014/10/14 2015/03/01];
c1 = [2012/04/16 2013/06/23 2015/04/08];
d1 = [2013/09/15 2014/01/19 2016/09/13];
e1 = [2015/04/01 2016/04/04 2018/08/04];
% H
a2 = [2012/07/23 2015/06/25 2016/05/20];
b2 = [2009/06/22 2014/09/14 2015/11/01];
c2 = [2006/04/16 2013/12/23 2015/06/08];
d2 = [2008/09/15 2014/05/19 2016/02/13];
e2 = [2011/04/01 2016/05/04 2018/03/04];
% HS
a3 = [2009/07/23 2010/06/25 2018/02/20];
b3 = [2011/06/22 2014/07/14 2016/09/01];
c3 = [2013/04/16 2016/09/23 2019/05/08];
d3 = [2013/09/15 2018/05/19 2019/06/13];
e3 = [2014/04/01 2019/01/04 2019/12/04];
% T
t = [1 2 3 4 5];
dates = [a1 a2 a3; b1 b2 b3; c1 c2 c3; d1 d2 d3; e1 e2 e3];
% Plotted
figure
barh(t, dates, 'hist')
title('Script')
xlabel('Time')
ylabel('Tail')
legend({'S','H','HS'})
legend('Location', 'southoutside')
legend('Orientation','horizontal')
If you plot this, you will notice that there are 9 bar graphs associated with each 't'. There should be only three as stated in the 'dates' variable per t. How do I stack 'a1,a2,a3, then b1,b2,b3 ...... and e1,e2,e3 each individually' to accomplish this feat?
My script result:
What I want the output to look like
Note: 1. The y axis contains the 5 different elements 't'
2. The x axis should contain the date elements 'dates'
3. When you plot these values, there are 9 bars. There should be three per
't'.
4. On the x axis, I would like to have the dates represented.
5. I would like to eventually be able to create a user prompted system that
allows people to enter in dates for a corresponding array, and have that
date be stacked onto the chart.
The following bit of code does a bit of what I ask for but with the bars stacked vertically not horizontally, and also takes in different user inputs.
https://www.mathworks.com/matlabcentral/fileexchange/32884-plot-groups-of-stacked-bars
You are very close to a solution. Download that file from MATLAB file exchange, open it, replace bar with barh, you got your own horizontally stacked bar plot.
Your input does not fit the expected format, the function expects a 3d matrix. A minor change to your code:
dates = [cat(3,a1,a2,a3);cat(3,b1,b2,b3); cat(3,c1,c2,c3); cat(3,d1,d2,d3); cat(3,e1,e2,e3)];
plotBarHStackGroups(dates,t)
I am new to Matlab, stuck with understanding data types(especially cell), probably there is an elegant solution I do not know about.
I have a cell which contains other cells with dates:
30/09/2005
30/12/2005
...
30/09/2016
I have also a cell with cells containing corresponding values:
1
5
...
3
I want to interpolate those values for all days/ or working days( better for me).
What I have been thinking to do is:
use datenum to receive numbers corresponding to the dates;
plug these dates( now numbers), corresponding values, and all dates( now numbers) in between them, into interp1.
Seemed a good plan but function
datenum('30/12/2005') = 13297
datenum('30/09/2016') = 13217
gives numbers which can not be used as earlier date is bigger than later one.
You can add any number of days to a datetime.
t = datetime('now') + days(1);
In addition it can give you the amount of days of a duration. Hence:
t0 = datetime('30/09/2005');
tEnd = datetime('30/09/2016');
durationInDays = days(tEnd - t0);
myDates(0) = t0;
for i = 2:durationInDays
myDates(i) = myDates(i-1) + days(1);
end
Following on from: Detecting if any values are within a certain value of each other - MATLAB
I am currently using randi to generate a random number from which I then subtract and add a second number - generated using poissrnd:
for k=1:10
a = poissrnd(200,1);
b(k,1) = randi([1,20000]);
c(k,1:2) = [b(k,1)-a,b(k,1)+a];
end
c = sort(c);
c provides an output in this format:
823 1281
5260 5676
5372 5760
5379 5779
6808 7244
6869 7293
9203 9653
12197 12563
14411 14765
15302 15670
Which are essentially the boundaries +/- a around the point chosen in b.
I then want to set an additional variable (i.e. d = 2000) which is used as the threshold by which values are matched and then merged. The boundaries are taken into consideration for this - the output of the above value when d = 2000 would be:
1052
7456
13933
The boundaries 823-1281 are not within 2000 of any other value so the midpoint is taken - reflecting the original value. The next midpoint taken is between 5260 and 9653 because as you go along, each successive values is within 2000 of the one before it until 9653. The same logic is then applied to take the midpoint between 12197 and 15670.
Is there a quick and easy way to adapt the answer give in the linked question to deal with a 2 column format?
EDIT (in order to make it clearer):
The values held in c can be thought of as demarcating the boundaries of 'blocks' that sit on a line. Every single boundary is checked to see if anything lies within 2000 of it (the black lines).
As soon as any black line touches a red block, that entire red block is incorporated into the same merge block - in full. This is why the first midpoint value calculated is 1052 - nothing is touched by the two black lines emanating from the first two boundaries. However the next set of blocks all touch one another. This incorporates them all into the merge such that the midpoint is taken between 9653 and 5260 = 7456.
The block starting at 12197 is out of reach of it's preceding one so it remains separate. I've not shown all the blocks.
EDIT 2 #Esteban:
b =
849
1975
8336
9599
12057
12983
13193
13736
16887
18578
c =
662 1036
1764 2186
8148 8524
9386 9812
11843 12271
12809 13157
12995 13391
13543 13929
16687 17087
18361 18795
Your script then produces the result:
8980
12886
17741
When in fact it should be:
1424
8980
12886
17741
So it is just missing the first value - if no merge is occurring, the midpoint is just taken between the two values. Sometimes this seems to work - other times it doesn't.
For example here it works (when value is set to 1000 instead of 2000 as a test):
c =
2333 2789
5595 6023
6236 6664
10332 10754
11425 11865
12506 12926
12678 13114
15105 15517
15425 15797
19490 19874
result =
2561
6129
11723
15451
19682
See if this works for you -
th = 2000 %// threshold
%// Column arrays
col1 = c(:,1)
col2 = c(:,2)
%// Position of "group" shifts
grp_changes = diff([col2(1:end-1,:) col1(2:end,:)],[],2)>th
%// Start and stop positions of shifts
stops = [grp_changes ; 1]
starts = [1 ; stops(1:end-1)]
%// Finally the mean of shift positions, which is the desired output
out = floor(mean([col1(starts~=0) col2(stops~=0)],2))
Not 100% sure if it will work for all your samples... but this is the code I came up with which works with at least the data in your example:
value=2000;
indices = find(abs(c(2:end,1)-c(1:end-1,2))>value);
indices = vertcat(indices, length(c));
li = indices(1:end-1)+1;
ri = indices(2:end);
if li(1)==2
li=vertcat(1,li);
ri=vertcat(1,ri);
end
result = floor((c(ri,2)+c(li,1))/2)
it's not very clean and could surely be done in less lines, but it's easy to understand and it works, and since your c will be small, I dont see the need to further optimize this unless you will run it millions of time.
i have a graph to plot, with dates in each axis, in x axis i have a date that represent the date pictures of taks was taken, and in the y-axis i would like to put the finish dates of that task, my query returns something like this
Task PictureDate FinishDate
A 01-03-2010 20-05-2010
A 08-03-2010 20-05-2010
A 15-03-2010 22-05-2010
B 01-03-2010 12-06-2010
B 08-03-2010 13-06-2010
B 15-03-2010 14-06-2010
I can not put the Finishdate in y-axis, is there a workaround i can use to display y-axis label as date?
I don't know if it could apply for this, but in .Net we can use a DateTime as a double by doing.
Datetime dt = new DateTime()
double l = dt.toOADate();
dt = Datetime.FromOADate(double l);
Maybe by giving a format or axistype or something like this you can do it.