<?xml version="1.0" encoding="UTF-8"?>
<rss  xmlns:atom="http://www.w3.org/2005/Atom" 
      xmlns:media="http://search.yahoo.com/mrss/" 
      xmlns:content="http://purl.org/rss/1.0/modules/content/" 
      xmlns:dc="http://purl.org/dc/elements/1.1/" 
      version="2.0">
<channel>
<title>Old Gang Consulting</title>
<link>https://www.oldgang.net/notebooks/</link>
<atom:link href="https://www.oldgang.net/notebooks/index.xml" rel="self" type="application/rss+xml"/>
<description></description>
<generator>quarto-1.10.18</generator>
<lastBuildDate>Wed, 15 Jan 2025 00:00:00 GMT</lastBuildDate>
<item>
  <title>Drawdown_Ivy: An Ivy tool to Model Pension Drawdown</title>
  <dc:creator>John Bates</dc:creator>
  <link>https://www.oldgang.net/notebooks/posts/drawdown_ivy/drawdown_ivy.html</link>
  <description><![CDATA[ 




<p>Drawdown_Ivy is an <a href="https://pkg.go.dev/robpike.io/ivy">Ivy</a> script to model retirement pension drawdown. It is a slightly simplified implementation (in Ivy) of the Drawdown tool that I previously implemented in Go, and which is described <a href="../../../notebooks/posts/drawdown_go/drawdown_go.html">here</a>.</p>
<p>Apart from the implementation language, the biggest difference between the Ivy drawdown tool and the Go drawdown tool is that the Go tool has the ability to model more complex income sources. It also has the ability to pay taxes within the year in which they are raised. The Ivy tool accumulates a value for the taxes due and adds that value onto the amount needed the following year. I have since added an option to allow the Go tool to do this as it seems to more closely match our behaviour in real life.</p>
<p>The Ivy code for Drawdown_Ivy can be found on GitHub <a href="https://github.com/Vextasy/Drawdown_Ivy/blob/master/drawdown.ivy">here</a>.</p>
<p><strong>Usage</strong></p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb1-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">ivy</span> ./drawdown.ivy</span></code></pre></div></div>
<p>The program will print its results in CSV format to standard output. The output is largely the same as the un-summarised output of the Go implementation of the drawdown tool and its examples of <a href="../../../notebooks/posts/drawdown_go/drawdown_go.html#examples-of-output---normal-mode">output in Normal Mode</a> give an indication of what could be created from this output.</p>
<p>Microsoft Excel is a good tool for viewing the output. In particular, a pivot table and pivot chart give a good visualisation of how things are changing from year to year.</p>
<p>A stacked bar chart (Figure 1) can be used to show the makeup of each yearly withdrawal.</p>
<div class="quarto-figure quarto-figure-left">
<figure class="figure">
<p><img src="https://www.oldgang.net/notebooks/posts/drawdown_ivy/ivy_withdrawal_chart.png" class="img-fluid figure-img"></p>
<figcaption>Figure 1 - Yearly Withdrawals by Source</figcaption>
</figure>
</div>
<p>In this example you can see that, state pension 2 kicks in in year 4 and that, in addition to the two state pensions, we are drawing from our private pension but not the general investment account or our savings.</p>
<div class="quarto-figure quarto-figure-left">
<figure class="figure">
<p><img src="https://www.oldgang.net/notebooks/posts/drawdown_ivy/ivy_withdrawal_table.png" class="img-fluid figure-img"></p>
<figcaption>Figure 2 - Table of Yearly Withdrawals by Source</figcaption>
</figure>
</div>
<p>The tabular view (Figure 2) gives an alternative view of the same data.</p>
<div class="quarto-figure quarto-figure-left">
<figure class="figure">
<p><img src="https://www.oldgang.net/notebooks/posts/drawdown_ivy/ivy_balance_chart.png" class="img-fluid figure-img"></p>
<figcaption>Figure 3 - End of Year Balance by Source</figcaption>
</figure>
</div>
<p>Figure 3 shows how the balance of the non-state pension sources changes over time. Our pension balance is almost depleted after 30 years but, because we are not drawing from them, our savings and general investment account balances continue to grow.</p>
<p>This Ivy implementation is simpler in its aims (than the Go implementation) but is still a useful tool for investigating the effect of environmental conditions on a pension pot. This document describes the implementation (mostly) for my own benefit.</p>
<p>The Ivy implementation is considerably shorter in terms of the number of lines of code when compared to the Go implementation. Even though a seasoned Ivy programmer would consider my coding style to be far from terse, and I almost certainly fail to spot several coding idioms that would result in more compact code, the Ivy implementation is 170 lines long whereas the Go implementation is just over 1000 lines long.</p>
<p>The remainder of this document annotates the source code.</p>
<section id="constants" class="level2">
<h2 class="anchored" data-anchor-id="constants">Constants</h2>
<p>There are a number of constants that are defined at, or near, the top of the Ivy script (drawdown.ivy) that are intended to be experimented with.</p>
<pre class="ivy"><code># Rates. All percentages
Igr = 3.5 / 100     # Investment Growth Rate
Sgr = 3.0 / 100     # Savings Growth Rate
Inf = 2.0 / 100     # Annual Inflation Rate
Pcr = 0.25 / 100    # Platform Charge Rate
Tbr = 0.5 / 100     # Tax Band Annual Percentage Increase

# Starting Parameters
N = 30              # Number of years to iterate.
Year1Income = 35000 # Income to draw each year.</code></pre>
<p><code>Igr</code> and <code>Sgr</code> are the percentage growth rates that are to be assumed will apply over the course of the iterations to investment sources and savings sources. An investment source might be a stocks and shares ISA or a pension fund. A savings source might be a cash savings account or other fixed income instrument, such as a bond. The only real distinction between the two being that you might consider, say, the investment source to have a higher likely annual growth rate than a savings source.</p>
<p><code>Inf</code> allows a figure to be given for the expected average annual percentage inflation rate over the whole period. Each year the iterations will increase the <em>needed</em> amount of income by this percentage.</p>
<p><code>Pcr</code> determines the amount of platform charge that is paid each year. Before any withdrawals are made from the sources a platform charge is added to the <em>needed</em> amount of income. The amount of the platform charge is <code>Pcr</code> percent of the remaining asset value at the start of the year. In calculating this asset value we ignore any state pension sources - we assume that they have no platform charge levied on them.</p>
<p>When calculating the tax to be paid each year we consider the tax regimes that are associated with each kind of source. A tax regime, such as capital gains tax or income tax, has a sequence of monetary bands and a percentage tax rate associated with each band. In order to reflect the fact that these bands might increase in value over the years we scale them up by a percentage equal to <code>Tbr</code> at the end of each year.</p>
<p>The constant <code>N</code> determines the number of years over which we will iterate. Our output will contain year end values for each year from 1 to <code>N</code>.</p>
<p><code>Year1Income</code> is the amount of income that we would like to draw in the first year of the iteration. At the start of each subsequent year this amount will be scaled up by the rate of inflation, <code>Inf</code>. This amount, to which we add any unpaid tax from the previous year and our platform charges, forms the amount of <em>needed</em> income that we will withdraw from the various sources.</p>
</section>
<section id="tax-regimes" class="level2">
<h2 class="anchored" data-anchor-id="tax-regimes">Tax Regimes</h2>
<pre class="ivy"><code># Tax Regimes:upper bound and percentage rate
IncReg = (12540 0.0) (50270 20.0) (125140 40.0) (100000000 45.0)
CapReg = (3000 0.0) (100000000 18.0)</code></pre>
<p>A tax regime is implemented as an array of pairs of values. Each pair contains an upper bound amount and a percentage rate. The pairs are assumed to be in order of increasing upper bound amount. Together these pairs form a sequence of tax brackets within which the associated percentage of tax will be charged. For example, the income tax regime above <code>IncReg</code> consists of four bands:</p>
<ol type="1">
<li>£0 to £12,540 at which no tax will be charged.</li>
<li>£12,541 to £50,270 at which tax will be charged at the rate of 20%.</li>
<li>£50,271 to £125,140 at which tax will be charged at the rate of 40%.</li>
<li>£125,141 and above at which tax will be charged at the rate of 45%.</li>
</ol>
<p>The “and above” bit is represented by the use of a very large upper bound.</p>
</section>
<section id="tax-accounts" class="level2">
<h2 class="anchored" data-anchor-id="tax-accounts">Tax Accounts</h2>
<pre class="ivy"><code># Tax Accounts: Tax Regime, taxed amount, tax
IncT = IncReg 0 0
IncT2 = IncReg 0 0
CapT = CapReg 0 0
TA = IncT IncT2 CapT    # Tax Accounts</code></pre>
<p>A tax account is associated with each taxable source. A tax account contains three pieces of information:</p>
<ol type="1">
<li>The tax regime to use when calculating tax on income drawn from sources that use this tax account.</li>
<li>The amount, within the current year, on which tax has already been calculated for sources that use this tax account.</li>
<li>The amount, within the current year, of tax that has been calculated for sources that use this tax account.</li>
</ol>
<p>A tax account may be shared between more than one source. For example, a state pension source might share the same tax account as a private pension source so that, when calculating income tax, the income drawn from each source is combined.</p>
<p>The global array <code>TA</code> contains the complete set of tax accounts in use by the program. This is initialised using <code>IncT</code>, <code>IncT2</code> and <code>CapT</code> as templates.</p>
</section>
<section id="sources" class="level2">
<h2 class="anchored" data-anchor-id="sources">Sources</h2>
<p>Sources are perhaps the central focus of the drawdown program. We model the remaining balance of each of the sources as we make annual withdrawals, and as the assets within each source increase in value each year.</p>
<pre class="ivy"><code># Sources
S = ("State Pension 1" "State Pension 2" "Savings" "Pension" "GIA") # Source names
B = 0 0 40000 500000 50000                          # Opening balance
TAI = 1 2 0 1 3                                     # Index into Tax Accounts, 0 if non-taxable

# Source flags
IsInv = 0 0 0 1 1                                   # Is an investment source
IsSav = 0 0 1 0 0                                   # Is a savings source
IsSP  = 1 1 0 0 0                                   # Is source a state pension</code></pre>
<p>The global array <code>S</code> contains the names of each of the sources that the program will consider. Several other global arrays (and indeed local variables to operators) have the same shape (length) as <code>S</code>. Ivy does not allow us to model pointers to elements of the source array so, instead, we work with indexes into it and maintain a number of other arrays that keep the same order as the source array.</p>
<p>The global array <code>B</code> contains the opening balance (opening asset value) of each of the sources in <code>S</code>. The balances are arranged in the same order as the sources in <code>S</code>. So, for example, we can see that we start the iteration with a “Savings” balance of £40,000 (the actual currency is not important, but it is assumed to be the same currency for all sources). We do not consider state pensions to have an opening balance. Instead, we populate the “balance” of a state pension source with a suitably scaled value at the start of each year.</p>
<p>The <em>ith</em> entry in the global array <code>TAI</code> gives the index into the tax account array <code>TA</code> at which the tax account for the <em>ith</em> source can be found. It contains a zero for sources that are non-taxable. For example, to find the tax account for the general investment account source (GIA) we note that the GIA source is in index position 5 of the source array <code>S</code> so we look at the contents of index position 5 in the tax account index array <code>TAI</code> and we find the value 3. This tells us that the tax account to use for the GIA source can be found in index position 3 of the tax account array <code>TA</code>.</p>
<p>The lack of pointers means that we have to be careful to ensure that if we change the ordering of sources in <code>S</code> then we also need to make the same ordering changes in other places.</p>
<p>The global constants <code>IsInv</code>, <code>IsSav</code>, and <code>IsSP</code> are set to 1 (true) for those sources that are investment sources, savings sources or state pension sources respectively, otherwise they contain a 0 in the position that corresponds to a source. You can see that a source is marked as belonging to only one of those categories.</p>
</section>
<section id="state-pension-sources" class="level2">
<h2 class="anchored" data-anchor-id="state-pension-sources">State Pension Sources</h2>
<p>We handle state pensions slightly differently to the way in which we handle other sources.</p>
<pre class="ivy"><code># State Pension Sources
SPStartYear = 1 4 0 0 0 # If a state pension, what is its start year?
SPY1 = 10000            # State Pension Year1 Amount
SPAPI = 2.5/100         # State Pension Annual Percentage Increase</code></pre>
<p>We might be modelling the assets of a couple, in which case we might have more than one state pension source and it is quite possible that they do not all come online in the same year. The global array <code>SPStartYear</code> contains the number of the year in which a given state pension source is to come online. It should contain a 0 in the index position for sources that are not state pension sources.</p>
<p>The constant <code>SPY1</code> contains the annual amount that a state pension will pay in year 1 of the iteration. This amount is scaled up by a percentage governed by the value of the <code>SPAPI</code> constant.</p>
</section>
<section id="draw-sequence" class="level2">
<h2 class="anchored" data-anchor-id="draw-sequence">Draw Sequence</h2>
<pre class="ivy"><code># Order by draw sequence
DS = 1 2 3 4 5          # Draw Sequence
S = S[DS]
B = B[DS]
TAI = TAI[DS]
IsInv = IsInv[DS]
IsSav = IsSav[DS]
IsSP = IsSP[DS]
SPStartYear = SPStartYear[DS]</code></pre>
<p>This Ivy implementation of the drawdown program will withdraw amounts from the sources in the order in which they are found in the source array <code>S</code>. Because there are several other global arrays that depend on the ordering of the sources in that array there is a mechanism that allows the sequence to be altered safely. The technique is to change the global draw sequence array <code>DS</code>. This array contains the order of indexes into the source array from which withdrawals will be made. As you can see from the code above the implementation of this is to simply reorder the source array and, at the same time, all of the other global arrays that must be kept in step with it.</p>
<p>If, for example, we wanted to preserve our savings and, instead, draw first from our pension and general investment account we could change the draw sequence to do so:</p>
<pre class="ivy"><code>DS = 1 2 4 5 3          # Draw Sequence</code></pre>
<p>In practice you may not need to make any changes here, but at least it identifies those global arrays whose ordering is dependent on the ordering of the source array.</p>
</section>
<section id="withdrawals" class="level2">
<h2 class="anchored" data-anchor-id="withdrawals">Withdrawals</h2>
<p>The withdrawal functions start with a scalar <code>need</code> amount and an array of remaining balances (one for each of the sources and in source order). The <code>need</code> amount is the annual amount that must be supplied from the sources to satisfy the inflation adjusted income requirements, the platform costs and the previous year’s tax costs in the current year. The job of the withdrawal functions is to step through the remaining balance array withdrawing as much as is available from each source until an amount equal in total to <code>need</code> has been found.</p>
<pre class="ivy"><code># Withdraw upto need (scalar) from the balances starting at the ith balance.
# Return the new balances
op i withdraw (need balances) =
    balance = balances[i]
    got = 0 max need min balance
    (i == count balances) : got 
    got,  (i + 1) withdraw ((need - got) balances)

# Withdraw need (scalar) from the balances returning the new balances
op withdraw (need balances) =
    b = 1 withdraw (need balances)
    b</code></pre>
<p>The dyadic version of <code>withdraw</code> is passed (an array containing) a scalar need amount and an array of remaining balances in source order as its right hand argument and a starting index into the balance array as its left argument. The balance array is guaranteed to have the same length as the source array. The balance in the <em>ith</em> index of the array is the remaining balance of the source in the <em>ith</em> position of the source array <code>S</code>.</p>
<p>The aim of <code>withdraw</code> is to find an amount equal to <code>need</code> by withdrawing as much as possible from each of the source balances in order. It returns a withdrawal array of length equal to <code>(count S) - (i-1)</code> with the amount in the first position being the amount that is to be withdrawn from the <em>ith</em> source. Here <code>count S</code> is the length of the source array.</p>
<p>The function focuses on the <em>ith</em> balance. The value <code>got</code> is calculated by first taking the minimum of what we need and the available balance. The restriction that got must be positive is there to protect against being called with a negative balance or need.</p>
<p>If <code>i</code> is equal to the length of <code>balances</code> it returns the scalar got. Otherwise it returns the result of catenating the value of <code>got</code> with the result of calling <code>withdraw</code> with an index of (i+1) and a need amount that has been reduced by the amount that we have <code>got</code> from the source in the <em>ith</em> position.</p>
<p>The monadic version of <code>withdraw</code> returns the result of calling this function with an index of 1.</p>
</section>
<section id="tax" class="level2">
<h2 class="anchored" data-anchor-id="tax">Tax</h2>
<p>Given the withdrawal array (which is the amount that we propose to withdraw from each source) the job of the tax operators is to calculate an array of tax amounts that will be raised as a result of withdrawing the amounts <code>w</code> from the sources.</p>
<p>The amount of tax due from a particular source will depend upon the withdrawn amount, the tax regime associated with the tax account that is associated with the source, and also the amount that has previously been withdrawn from other sources using the same tax account. To be able to calculate this latter figure the tax account contains a running total of the amount withdrawn from all of the sources associated with the tax account. This running total is reset at the end of each year.</p>
<pre class="ivy"><code>op second a = 1 take 1 drop a

# Calculate the amount of tax due for the amount 'a'
op tr taxDue a =
    u = first@ tr                           # upper bounds
    r = second@ tr                          # tax rates
    ba = (a min u) - (a min -1 drop (0,u))  # amounts in each bracket
    t = +/(ba * r/100)                      # sum of (bracket amount times rate)
    t

# Calculate tax on the ith source given w[i] withdrawn.
# Return zero for non-taxable sources.
# The tax account contains the already withdrawn amount from other sources in the same tax account.
# Update the tax account with the amount withdrawn and tax calculated.
op i taxOn ws = 
    tai = TAI[i]                        # tax account index
    (tai == 0): 0
    ta = TA[tai]                        # tax account
    tr = ta[1]                          # tax regime
    w0 = ta[2]                          # amount that tax has already been calculated on (from other sources)
    w = ws[i]                           # withdrawn amount from this source
    t0 = ta[3]                          # tax already calculated (from other sources)
    t = (tr taxDue (w0+w)) - (tr taxDue (w0))   # additional tax
    TA[tai] = ta[1] (w + w0) (t + t0)           # accumulate taxed amount and tax (raised)
    t

# Calculate the tax to pay on each element of w
op taxOn w =
    (iota count S) @taxOn w                 # tax due</code></pre>
<p>The monadic <code>taxOn</code> operator is called with an array of withdrawals (one for each source). It calls the dyadic <code>taxOn</code> operator with a source index as its left argument.</p>
<p>The dyadic <code>taxOn</code> operator focuses on the <em>ith</em> source. It determines the tax account index by indexing into the tax account index array <code>TAI</code> and so finds the tax account.</p>
<p>From the tax account it extracts the tax regime <code>tr</code>, the amount of withdrawals that we have already calculated tax on using this tax account <code>w0</code>, and the tax that has already been calculated as being due on this tax account from other sources <code>t0</code>.</p>
<p>Then, using the amount that we have withdrawn from this <em>ith</em> source <code>w</code> it calculates the difference between the tax that would be due on a withdrawal of <code>(w0+w)</code> and an amount that would be due on a withdrawal of just <code>w0</code> - this is the additional tax <code>t</code>.</p>
<p>Finally it updates the tax account with the new values for the amount that has been taxed, <code>w+w0</code>, and the amount of tax raised, <code>t+t0</code>.</p>
<p>The <code>taxDue</code> operator takes a tax regime as its left argument and a scalar amount as its right argument. It returns the scalar amount of tax due, <code>t</code>, as a result of withdrawing the amount <code>a</code>.</p>
<p>It begins by extracting the array of upper bounds, <code>u</code>, and the array of associated tax rates, <code>r</code> from the tax regime.</p>
<p>It calculates the size of each of the tax brackets by subtracting <code>u</code> shifted right by one position (and with a zero prepended) from itself. But by carefully limiting the maximum value of either term to be <code>a</code> it results in an array of values of the same length as <code>u</code> but which contains the amount of <code>a</code> that falls into each bracket, <code>ba</code>.</p>
<p>It is then easy to calculate a scalar tax value by summing over the product of the rate in <code>r</code> and the amount in <code>ba</code>. This value, <code>t</code>, is then returned.</p>
</section>
<section id="year-start-and-year-end" class="level2">
<h2 class="anchored" data-anchor-id="year-start-and-year-end">Year Start and Year End</h2>
<p>At the start of the year we initialise the state pension balances and scale up the investment and savings balances using the appropriate scaling constants.</p>
<pre class="ivy"><code># Start year n with balances b.
# Return new balances (after any scaling up)
op startYear (n b) =
    ids = iota count b
    # set state pensions
    i = (IsSP and (n &gt;= SPStartYear))           # identify state pensions
    b[i sel ids] = SPY1 * (1 + SPAPI) ** n - 1  # set their scaled up balance
    #
    # scale up investments and savings (apart from in year 1)
    (n == 1): b
    b[IsInv sel ids] = b[IsInv sel ids] * 1 + Igr 
    b[IsSav sel ids] = b[IsSav sel ids] * 1 + Sgr 
    b

# Reset the counters in the tax account with index 'tai'
op resetAndScaleTaxAccount tai =
    ta = TA[tai]                # tax account
    tr = ta[1]                  # tax regime
    m=mix tr                    # as an nx2 matrix. first column contains the bands.
    m[;1] = m[;1] * 1 + Tbr     # scale the bands
    tr = split m                # return to vector shape
    TA[tai] = tr 0 0            # set scaled tax regime, and zero taxed amount and tax counters

op endYear (n b) =
    resetAndScaleTaxAccount@ iota count TA
    b</code></pre>
<p>State pension balances are assumed to be fully withdrawn each year.</p>
<p>At the end of the year we scale the bands in the tax account tax regime up using the appropriate percentage constant and we reset the taxed amount and tax raised counters in the tax account</p>
</section>
<section id="yearly-iteration" class="level2">
<h2 class="anchored" data-anchor-id="yearly-iteration">Yearly Iteration</h2>
<pre class="ivy"><code>UnpaidTax = 0
# Iterate year n with starting balance b. Return balance, withdrawals, and tax incurred at year end.
op n year b =
    need = Year1Income * (1 + Inf) ** n - 1     # scale by inflation.
    need = need + UnpaidTax                     # add in unpaid tax from the previous year.
    UnpaidTax = 0
    b = startYear n b   
    pc = (+/ b[(not IsSP) sel iota count b]) * Pcr  # platform charge
    need = need + pc            # add in platform charge
    w = withdraw (need b)       # withdrawn amounts that sum to need
    t = taxOn w                 # calculate tax according to the tax regimes
    UnpaidTax = +/ t            # set UnpaidTax for payment next year.
    b = endYear n b
    (b - w)  w t                # end of year balance, withdrawals, and tax
    

# Return the balance after maxN years
# given the starting balances, withdrawals and taxes
# at the end of the previous 1...n years (n &lt;= maxN).
op maxN years (n bs ws ts) =
    b w t = n year bs[n]        # balances, withdrawals and tax at the end of year n
    bs = bs ,% b                # append as row to bs
    ws = ws ,% w                # append as row to ws
    ts = ts ,% t                # append as row to ts
    (n == maxN): bs ws ts       # on reaching year maxN, return the accumulated rows.
    maxN years (n+1) bs ws ts   # otherwise recurse to return years (n+1) and above.
</code></pre>
<p>The work of calculating the effect of a single year is performed by the <code>year</code> operator. Given a starting balance array <code>b</code> (of length equal to the number of sources) and a year number <code>n</code> we calculate the end of year balance array, and return it with the withdrawal array and tax array.</p>
<p>The amount of income needed for the year is calculated by scaling up the <code>Year1Income</code> constant by the rate of inflation compounded over (n-1) additional years. To this we add any (unpaid) tax that was raised by withdrawals in the previous year, and the platform charges.</p>
<p>Unpaid tax is maintained in a global variable, a rather clumsy mechanism that requires that the <code>year</code> operator is called with consecutive values of <code>n</code> - which it is. The global <code>UnpaidTax</code> is initialised immediately above the <code>year</code> operator to stress its local nature.</p>
<p>The platform charge is determined as a percentage of the balance of the non-state pension sources.</p>
<p>The <code>years</code> operator recursively iterates through years from n up to maxN years (where n &lt; maxN) calling <code>year</code> for each new value of <code>n</code> and appending the returned balance, withdrawal and tax arrays, <code>b</code>, <code>w</code>, and <code>t</code>, as new rows on the <code>bs</code>, <code>ws</code>, and <code>ts</code> matrices.</p>
<p>The end result is that the data for year n appears in the <em>nth</em> row of each of these matrices. Once we reach year n we return the completed matrices and no further recursion occurs.</p>
</section>
<section id="execution-and-the-output-of-csv-data" class="level2">
<h2 class="anchored" data-anchor-id="execution-and-the-output-of-csv-data">Execution and the Output of CSV Data</h2>
<pre class="ivy"><code># Unpack the year, source name, amount withdrawn, tax raised,
# and year-end balance for each combination of year and source. 
op (n i) byYearSource (s bs ws ts) = 
     n s[i] ws[n;i] ts[n;i] bs[n;i]

op a csv b = (text a) , ',' , (text b)


# Run for n years with b as the opening balance.
op run (n b) = 
    bs = 1 (count b) rho b  # matrix with b as the only row
    ws = 0 (count b) rho 0  # empty matrix of the same shape 
    ts = 0 (count b) rho 0  # empty matrix  of the same shape
    bs ws ts = n years 1 bs ws ts
    bs = 1 drop bs          # drop the opening balance
    year_source = , (iota n) o., (iota count S)
    M = year_source @byYearSource S bs ws ts
    print "Year, Source, Withdrawn, Tax Raised, Balance"
    mix csv/mix M

run N B</code></pre>
<p>The monadic operator <code>run</code> takes a single array parameter which contains two values: a number of years, <code>n</code>, for which to run the iteration, and an array, <code>b</code>, which contains the opening balance for each of the sources.</p>
<p>The aim of <code>run</code> is to use <code>years</code> to iterate over the given number of years using the starting balances. It does this by calling the dyadic operator <code>years</code> with a starting year of 1 and an ending year of n and capturing the returned matrices. The returned matrices contain the end of year balances, within year withdrawal amount, and within year tax amount. Year n data is in the <em>nth</em> row of each matrix.</p>
<p>There is a little trick in the bootstrapping of the balances array: the <code>years</code> operator expects to find the opening balances for year n in the <em>nth</em> row of the <code>bs</code> matrix that is passed to it as an argument. So we initialise <code>bs</code> with the passed in opening balances and then when <code>years</code> returns we drop the initial opening balance from <code>bs</code> so that it contains the closing balances for year n in the <em>nth</em> position and has a length of n - the same as the lengths of both <code>ws</code> and <code>ts</code>.</p>
<p>To output the CSV we use the monadic <code>print</code> operator to output our textual header. We construct a single array <code>year_source</code> that contains an entry for each combination of year (1 to n) and source index (1 to count S). We do this with the outer join operator <code>o.</code> applied to the catenation operator (dyadic <code>,</code>) and then ravel the whole thing into a one-dimensional array with the ravel operator (monadic <code>,</code>).</p>
<pre class="ivy"><code>year_source = , (iota n) o., (iota count S)</code></pre>
<p>This gives us a vector that, for n = 30 and 4 sources, looks like this:</p>
<pre><code>(1 1) (1 2) (1 3) (1 4) (2 1) (2 2) (2 3) (2 4) (3 1)...(30 4)</code></pre>
<p>We construct a dyadic operator <code>byYearSource</code> that takes one of these year-and-source tuples as its left argument and the source, balance, withdrawal, and tax matrices as its right argument and which returns a vector containing the values of the CSV data that we would like to see on each line Such a line would correspond to year <code>n</code> and source (index) <code>i</code>.</p>
<pre class="ivy"><code>op (n i) byYearSource (s bs ws ts) = 
     n s[i] ws[n;i] ts[n;i] bs[n;i]</code></pre>
<p>We invoke “each left” on this operator to generate a matrix containing the CSV data that we would like to see in our output.</p>
<pre class="ivy"><code>M = mix year_source @byYearSource S bs ws ts</code></pre>
<p>Our matrix <code>M</code> contains a row for each year and a column for each of the 5 data values returned by <code>byYearSource</code> - year, source name, withdrawal, tax and balance.</p>
<p>We reduce across the rows with our <code>csv</code> operator which gives us a vector with an element for each value of year_source and with the data values separated by a comma. We lay these out one per line by applying <code>mix</code> again.</p>
<pre class="ivy"><code>mix csv/M</code></pre>
<p>Where the <code>csv</code> operator is defined (above) as:</p>
<pre class="ivy"><code>op a csv b = (text a) , ',' , (text b)</code></pre>
<p>Finally we invoke the <code>run</code> operator passing it, as values of <code>n</code> and <code>b</code>, the global constants <code>N</code> and <code>B</code> which were set near the top of the Ivy script.</p>
<p>The resultant text is printed to standard output and we capture it manually into a file, perhaps by invoking ivy from the shell, like this:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb20" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb20-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">ivy</span> drawdown.ivy <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span>drawdown.csv</span></code></pre></div></div>
<p>The output looks something like this:</p>
<pre class="csv"><code>Year, Source, Withdrawn, Tax Raised, Balance
1,State Pension 1,10000,0,0    
1,State Pension 2,0,0,0        
1,Pension,26475,4787,473525    
1,GIA,0,0,50000                
1,Savings,0,0,40000            
2,State Pension 1,10250,0,0    
2,State Pension 2,0,0,0        
2,Pension,31695,5868,458404    
...</code></pre>
<p>Such data can easily be read into a tool for analysis. Different outcomes can be modelled by changing the values of various constants and re-running the iteration:</p>
<ul>
<li><code>N</code>, to give the number of years on which to iterate.</li>
<li><code>B</code>, to modify the opening balances.</li>
<li><code>Igr</code>, <code>Sgr</code>, <code>Inf</code>, <code>Pcr</code>, <code>Tbr</code>, to see the effect of different rates.</li>
<li>The upper bounds and percentage tax rates of the different kinds of tax regime.</li>
<li>The order in which income is withdrawn from the sources in <code>S</code> (using the draw sequence in <code>DS</code>).</li>
<li>The state pension starting years and annual amounts and increases in <code>SPStartYear</code>, <code>SPY1</code> and <code>SPAPI</code>.</li>
</ul>
<p>More complicated scenarios can be modelled with the <a href="../../../notebooks/posts/drawdown_go/drawdown_go.html">Go version of Drawdown</a>.</p>


</section>

 ]]></description>
  <category>Ivy</category>
  <category>Pension Drawdown</category>
  <guid>https://www.oldgang.net/notebooks/posts/drawdown_ivy/drawdown_ivy.html</guid>
  <pubDate>Wed, 15 Jan 2025 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Drawdown_Go: A Go tool to Model Pension Drawdown</title>
  <dc:creator>John Bates</dc:creator>
  <link>https://www.oldgang.net/notebooks/posts/drawdown_go/drawdown_go.html</link>
  <description><![CDATA[ 




<p>Drawdown is a Go command line program that runs an iteration of a pension drawdown strategy to discover how it will unfold over time given a set of sources (pensions, investments, savings accounts) and growth rates (assumed rates of savings and investment growth and inflation) and a period of years over which drawdown will take place. The output of the program shows the balance remaining, the amount withdrawn, and the amount of tax paid at the end of each of the years.</p>
<p>When run with the “-s” command line flag the program will, instead, run the same strategy over each combination of several values of the growth rates to see the impact on the final balance, the amount withdrawn and the amount of tax paid.</p>
<p>The Go code for Drawdown can be found here: <a href="https://github.com/Vextasy/Drawdown_Go">https://github.com/Vextasy/Drawdown_Go</a>.</p>
<p><strong>Usage</strong></p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb1-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">./drawdown</span> <span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">[-</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">s</span><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">]</span> </span></code></pre></div></div>
<p>The -s flag causes the program to run in summary mode. The output from the program in normal mode will be found in the file <code>drawdown.csv</code>. When run in summary mode the output will be found in the file <code>summary.csv</code>. The output from both of these modes is suitable for use in other programs but, in particular, can be rendered into pivot tables or charts in Excel.</p>
<section id="example-data" class="level2">
<h2 class="anchored" data-anchor-id="example-data">Example Data</h2>
<p>The examples shown in this document are based on a simple drawdown strategy that simulates the impact of a withdrawal amount of £35,000 taken annually over a 30 year period for a couple beginning their pension drawdown and who:</p>
<ul>
<li>Each have a state pension of £10,000 per year with State Pension 1 starting immediately (year 0) and State Pension 2 starting after one year (year 1). The state pension is assumed to increase at the rate of 2.5% per year.</li>
<li>Have £40,000 of savings.</li>
<li>Have £40,000 in an ISA.</li>
<li>Have private pensions: “Pension 1” of £350,000 and “Pension 2” of £150,000.</li>
<li>Have £50,000 in a general investment account (GIA).</li>
</ul>
<p>In this model, private pensions are assumed to come with a tax-free lump sum of 25% as soon as they enter drawdown - they are effectively split into a taxable drawdown pension of 75% of the original value and a lump sum of 25% of the original value.</p>
<p>When drawdown is run in normal mode (i.e.&nbsp;without the “-s” flag) it uses a fixed set of rate parameters to calculate the situation at the end of each of the 30 years. When run with the “-s” flag it runs the same iterations to completion for every combination of values of the rate parameters.</p>
<p>When run in normal mode the following parameters are used:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode go code-with-copy"><code class="sourceCode go"><span id="cb2-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">const</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb2-2">    InvestmentGrowthRate     <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.5</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// %</span></span>
<span id="cb2-3">    SavingsGrowthRate        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.5</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// %</span></span>
<span id="cb2-4">    AnnualInflationRate      <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2.5</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// %</span></span>
<span id="cb2-5">    PlatformChargeRate       <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.25</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// The % charge for using a platform as a percentage of the balance.</span></span>
<span id="cb2-6">    TaxBandAnnualPctIncrease <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// %</span></span>
<span id="cb2-7"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span></code></pre></div></div>
<p>When run in summary mode the calculation is performed over every combination of the following values (taken at suitable steps):</p>
<ul>
<li>Investment Growth Rate from 0% to 8%.</li>
<li>Savings Growth Rate from 0% to 8%.</li>
<li>Annual Inflation Rate from 2% to 5%.</li>
<li>Platform Charge Rate from 0.1% to 0.5%.</li>
<li>Tax Band Annual Percentage Increase from 0% to 2%.</li>
</ul>
<p>These values are built into the program, as are the strategies themselves, but after making a change, a simple recompilation can be performed in less than a second. In this initial version of the program both the parameters and the strategies are altered by editing the Go code. A later version might move the rate parameters to a textual format file and allow the choice from a number of fixed strategies.</p>
</section>
<section id="examples-of-output---normal-mode" class="level2">
<h2 class="anchored" data-anchor-id="examples-of-output---normal-mode">Examples of Output - Normal Mode</h2>
<p>Actual output of the program takes the form of a CSV file. Different formats are generated for the normal and summary mode of operations but both are suitable for use in another program, such as Microsoft Excel, for the purposes of analysis and visualisation.</p>
<div class="quarto-figure quarto-figure-left">
<figure class="figure">
<p><img src="https://www.oldgang.net/notebooks/posts/drawdown_go/end_of_year_balances_by_source.png" class="img-fluid figure-img"></p>
<figcaption>Figure 1 - End of Year Balances by Source</figcaption>
</figure>
</div>
<p>Figure 1 displays an Excel stacked bar-chart that shows, for each of the 30 years for which the iterations were run, the total balance of funds remaining broken down by each source. You can see that the tax-free lump sums (TFLS) shown in orange and blue are exhausted by years 6 and 8 respectively. Also noticeable, is that the ISA balance grows in size up until about year 7, after which is decreases each year until it is used by by year 14. After year 14 the balance is contained wholly within the two pension funds (and also by a couple of state pensions that are not shown in this chart because we don’t consider them to have a balance).</p>
<div class="quarto-figure quarto-figure-left">
<figure class="figure">
<p><img src="https://www.oldgang.net/notebooks/posts/drawdown_go/income_by_source.png" class="img-fluid figure-img"></p>
<figcaption>Figure 2 - Income by Source</figcaption>
</figure>
</div>
<p>Figure 2 shows the income drawn from the sources each year as a stacked bar-chart with colours being used to identify the size of the contribution from each source. You can see that from year 16 onwards all of the income is coming from the combination of the two state pensions and pension 1. We can also see how a contribution from State Pension 2 didn’t occur until year 1 (because our strategy contains that information) and that because of that a larger amount was drawn from the ISA in year 0.</p>
<p>If you are wondering why the ISA, given that it is used to provide income through to year 15, continues to increase in size, it is because our strategy contains an action that transfers the maximum amount allowed each year from the savings account and the tax free lump sums into the ISA so that it can earn interest over the course of the year in a tax efficient way.</p>
<div class="quarto-figure quarto-figure-left">
<figure class="figure">
<p><img src="https://www.oldgang.net/notebooks/posts/drawdown_go/income_by_source_pivot.png" class="img-fluid figure-img"></p>
<figcaption>Figure 3 - Income by Source Pivot Table</figcaption>
</figure>
</div>
<p>Figure 3 shows a different view of the same information. This time in Pivot Table format you can see, for each of the 30 years, the amount drawn from each source to arrive at the desired annual total figure. The annual total required is calculated from an inflation adjusted annual amount which in this example was set at £35,000 per year. The reason why the total at the end of year 0 is greater than our chosen initial amount is that it is increased to include platform costs for hosting the drawdown pensions and investment and savings accounts. It will also, in later years, be increased by any amount of tax that is incurred when drawing sums from the non-tax-free instruments.</p>
<div class="quarto-figure quarto-figure-left">
<figure class="figure">
<p><img src="https://www.oldgang.net/notebooks/posts/drawdown_go/tax_raised_from_each_source.png" class="img-fluid figure-img"></p>
<figcaption>Figure 4 - Tax Raised from each Source Pivot Table</figcaption>
</figure>
</div>
<p>Figure 4 shows that very little tax needs to be paid for the first 15 years because we are mostly drawing income from tax-free sources or, as in the case of the GIA (general investment account), we are keeping our annual withdrawals below the appropriate capital gains tax allowance</p>
</section>
<section id="normal-mode-output---drawdown.csv" class="level2">
<h2 class="anchored" data-anchor-id="normal-mode-output---drawdown.csv">Normal Mode Output - Drawdown.csv</h2>
<p>The examples above are all built using the normal mode output found in <code>drawdown.csv</code> which looks like this (years 2 to 28 are omitted):</p>
<pre class="csv"><code>Year,Source,Amount,Tax,Tax Raised,Balance
0,"State Pension 1",10000,0,0,0
0,"State Pension 2",0,0,0,0
0,"Pension 1",0,0,0,262500
0,"TFLS 1",1000,0,0,86500
0,"Pension 2",0,0,0,112500
0,"TFLS 2",0,0,0,37500
0,"Savings",0,0,0,20000
0,"ISA",22600,0,0,37400
0,"GIA",3000,0,0,47000
1,"State Pension 1",10250,0,0,0
1,"State Pension 2",10250,0,0,0
1,"Pension 1",0,0,0,271687
1,"TFLS 1",1025,0,0,88502
1,"Pension 2",0,0,0,116437
1,"TFLS 2",0,0,0,38812
1,"Savings",0,0,0,200
1,"ISA",12898,10,0,46311
1,"GIA",3074,0,10,45570
...
29,"State Pension 1",20464,0,4092,0
29,"State Pension 2",20464,0,1197,0
29,"Pension 1",43854,9304,4015,73198
29,"TFLS 1",0,0,0,0
29,"Pension 2",0,0,0,305066
29,"TFLS 2",0,0,0,0
29,"Savings",0,0,0,0
29,"ISA",0,0,0,0
29,"GIA",0,0,0,0</code></pre>
<p>Each row gives the end-of-year state for a given year and source:</p>
<ul>
<li>The <code>Amount</code> column is the amount of money that was drawn from that source (including any tax) in the given year.</li>
<li>The <code>Tax</code> column is the amount of tax that was paid from this source in the given year.</li>
<li>The <code>Tax Raised</code> column is the amount of tax incurred as a result of drawing from this source in the given year.</li>
<li>The <code>Balance</code> column is the amount remaining in the source at the end of the given year.</li>
</ul>
<p>State pensions are assumed to have infinite balance but we return a value of zero for want of a better representation.</p>
<p>You can see from the year 29 rows above that at the end of the 30 year period we are left with a non-zero balance in both of the private pensions as well as still having the two state pensions. We can infer from this that this particular drawdown strategy has preserved the pension pots at the expense of the savings and ISA funds. An alternative strategy might be to drawdown from the pensions first, leaving the tax-free sources until later. This tool allows us to compare the outcome from such different strategies.</p>
</section>
<section id="summary-mode-output---summary.csv" class="level2">
<h2 class="anchored" data-anchor-id="summary-mode-output---summary.csv">Summary Mode Output - Summary.csv</h2>
<p>When we run the drawdown program with the “-s” flag we generate a summary output CSV file. In the summary output each row represents a complete iteration of the strategy over the given period of years (in this example 30 years). For each combination of the input rates we obtain values for each of the four output measures of interest.</p>
<pre class="csv"><code>Investment Growth Rate,Savings Growth Rate,Annual Inflation Rate,Platform Charge Rate,Tax Band Annual Percentage Increase,Total Withdrawn,Tax Paid,Final Balance,Final Year
igr_0.00, sgr_0.00, air_2.00, pcr_0.10, tbi_0.00, 1457098, 81846, 0, 28
igr_0.00, sgr_0.00, air_2.00, pcr_0.10, tbi_0.50, 1498026, 73899, 0, 29
igr_0.00, sgr_0.00, air_2.00, pcr_0.10, tbi_1.00, 1498026, 69204, 0, 29
igr_0.00, sgr_0.00, air_2.00, pcr_0.10, tbi_2.00, 1498026, 56253, 0, 29
igr_0.00, sgr_0.00, air_2.00, pcr_0.25, tbi_0.00, 1457098, 78323, 0, 28
igr_0.00, sgr_0.00, air_2.00, pcr_0.25, tbi_0.50, 1457098, 76125, 0, 28
igr_0.00, sgr_0.00, air_2.00, pcr_0.25, tbi_1.00, 1457098, 66809, 0, 28
igr_0.00, sgr_0.00, air_2.00, pcr_0.25, tbi_2.00, 1498026, 55659, 0, 29
...</code></pre>
<p>The example above shows the first few rows from our summary output file. Each row represents the end result of an iteration over 30 years and gives the following final values:</p>
<ul>
<li>The <code>Total Withdrawn</code> column is the sum of the amount withdrawn from all of the sources over the iteration (including tax).</li>
<li>The <code>Tax Paid</code> column is the sum of the amount of tax paid from all of the sources over the iteration.</li>
<li>The <code>Final Balance</code> column is the sum of the balance remaining across all of the sources at the end of the iteration.</li>
<li>The <code>Final Year</code> column is the year in which the sources were unable to supply the required needs, or the intended final year of the iteration (if a non-zero balance remains).</li>
</ul>
<p>These values are given for an iteration for each of several values of input rates:</p>
<ul>
<li>The <code>Investment Growth Rate</code> column contains the percentage rate at which non-savings investments are assumed to grow each year.</li>
<li>The <code>Savings Growth Rate</code> column contains the percentage rate at which savings investments are assumed to grow each year.</li>
<li>The <code>Annual Inflation Rate</code> column contains the rate at which the needed annual income is increased each year.</li>
<li>The <code>Platform Charge Rate</code> column contains the percentage of the total balance of a source that is charged in fees by the platform each year.</li>
<li>The <code>Tax Band Annual Percentage Increase</code> column contains the percentage rate at which the tax band rates are assumed to be increased each year.</li>
</ul>
<p>The summary mode output file <code>summary.csv</code> can be easily used by analysis programs, such as Microsoft Excel, to present this data in a useful format.</p>
</section>
<section id="examples-of-output---summary-mode" class="level2">
<h2 class="anchored" data-anchor-id="examples-of-output---summary-mode">Examples of Output - Summary Mode</h2>
<p>We can import the summary mode data into Excel and visualise it using a combination of pivot tables and charts.</p>
<div class="quarto-figure quarto-figure-left">
<figure class="figure">
<p><img src="https://www.oldgang.net/notebooks/posts/drawdown_go/final_balance_by_pcr_and_air.png" class="img-fluid figure-img"></p>
<figcaption>Figure 5 - Final Balance by Platform Charge and Inflation Rate</figcaption>
</figure>
</div>
<p>Figure 5 shows the effect on the final balance of different values of platform charge rate and annual inflation rate. By choosing to display the <em>average</em> final balance figure we can use slicers to select one or more values of each of the other rates and we obtain the average final balance over them. In this example we have averaged over investment and savings growth rates of 3% and 4%, and have fixed the tax band annual percentage increase at 0.5%. We can see from both the pivot table and the chart that with this strategy, its starting balances, annual withdrawal amount and our selected growth rates, the final balance is very dependent on the annual inflation rate. In particular, an annual inflation rate over the retirement period of 4% or higher will mean that we run out of funds before the 30 year period ends.</p>
<p>Another observation is that the level of charges levied by the platform also has a big impact on the final balance. Typically, unless we run out of funds, this is of the order of £150,000.</p>
<p>We can take a closer look at how long our sources will last under different input rates.</p>
<div class="quarto-figure quarto-figure-left">
<figure class="figure">
<p><img src="https://www.oldgang.net/notebooks/posts/drawdown_go/final_year_by_pcr_and_air.png" class="img-fluid figure-img"></p>
<figcaption>Figure 6 - Final Year by Platform Charge and Inflation Rate</figcaption>
</figure>
</div>
<p>Figure 6 shows that an annual inflation rate of 4% will result in our funds lasting somewhere between 24 and 26 years depending upon the platform charge rate (all other rates being as defined by the sliders).</p>
<p>There are a number of views of the data that can be obtained and which are all useful in understanding how a particular drawdown strategy will unfold given its input rates and starting balances.</p>
</section>
<section id="the-drawdown-strategy" class="level2">
<h2 class="anchored" data-anchor-id="the-drawdown-strategy">The Drawdown Strategy</h2>
<p>The elements that define a drawdown strategy are held in a DrawScenario struct.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode go code-with-copy"><code class="sourceCode go"><span id="cb5-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">type</span> DrawScenario <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb5-2">    Sources                  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]*</span>Source</span>
<span id="cb5-3">    DrawSequence             <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]*</span>Source</span>
<span id="cb5-4">    TaxPaymentSequence       <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]*</span>Source</span>
<span id="cb5-5">    TaxAccounts              <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">map</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[*</span>Source<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]*</span>TaxAccount</span>
<span id="cb5-6">    TaxRegimes               <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]*</span>TaxRegime</span>
<span id="cb5-7">    Actions                  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">func</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>year <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> need <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int64</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> s <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>DrawScenario<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb5-8">    InflationLinkedVariables <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]*</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int64</span></span>
<span id="cb5-9">    Rates                    DrawRates</span>
<span id="cb5-10"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<section id="sources" class="level3">
<h3 class="anchored" data-anchor-id="sources">Sources</h3>
<p>The Sources field contains a slice of the full set of Sources available to the strategy.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode go code-with-copy"><code class="sourceCode go"><span id="cb6-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Source represents something from which income can be drawn.</span></span>
<span id="cb6-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// This might be a savings account, an investment account, or a pension, for example.</span></span>
<span id="cb6-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">type</span> Source <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-4">    Name           <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">string</span></span>
<span id="cb6-5">    balance        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int64</span>                             <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// The amount of money currently in the source.</span></span>
<span id="cb6-6">    year           <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span>                               <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// The current year (origin zero) - decisions might be based on this.</span></span>
<span id="cb6-7">    startYear      <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">func</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>year <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span>                    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Called at the beginning of each year typically to set the opening balance (year origin is zero).</span></span>
<span id="cb6-8">    endYear        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">func</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>year <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span>                    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Called at the end of each year.</span></span>
<span id="cb6-9">    makeWithdrawal <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">func</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>amount <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int64</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span>SourceAmount <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// nil, else it returns the amount withdrawn from the source.</span></span>
<span id="cb6-10"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb6-11"></span>
<span id="cb6-12"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Type SourceAmount represents an amount of money associated with a given source.</span></span>
<span id="cb6-13"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">type</span> SourceAmount <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-14">    Source <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>Source</span>
<span id="cb6-15">    Amount <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int64</span></span>
<span id="cb6-16"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>In each year of the iteration, a <em>needed</em> amount is drawn from the sources in the order given by the DrawSequence field. Mechanisms exist to specify that a limit should be put on the amount drawn from a source, or that the amount drawn should be split between two sources, or drawn from a pool of sources in sequence. A source can also appear multiple times in the draw sequence - usually initially with some limit and then later as a source of last resort (when all earlier sources have been exhausted).</p>
<p>The makeWithdrawal function of Source returns a slice of SourceAmount structs. This allows synthetic sources to split withdrawals between a number of real sources.</p>
</section>
<section id="the-draw-sequence" class="level3">
<h3 class="anchored" data-anchor-id="the-draw-sequence">The Draw Sequence</h3>
<p>The draw sequence is the order in which money is withdrawn from the sources to satisfy the calculated amount of money needed each year. It might look something like this:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode go code-with-copy"><code class="sourceCode go"><span id="cb7-1">drawSequence <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]*</span>drawdown<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Source<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb7-2">        is_state_pension_1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb7-3">        is_state_pension_2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb7-4">        drawdown<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Seq<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(&amp;</span>capitalGainsTaxAllowance<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> is_gia<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span></span>
<span id="cb7-5">        drawdown<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Seq<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(&amp;</span>v1000<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> is_pension_1_tfls<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> is_savings<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> is_pension_2_tfls<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span></span>
<span id="cb7-6">        is_isa<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb7-7">        is_pension_1_tfls<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb7-8">        is_pension_2_tfls<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb7-9">        is_pension_1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb7-10">        is_pension_2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb7-11">        is_savings<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb7-12">        is_gia<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb7-13">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>In the example above, money is being taken from the sources in the following order:</p>
<ol type="1">
<li>state pensions first,</li>
<li>an inflation-adjusted tax-free amount from the general investment account,</li>
<li>an inflation-adjusted £1,000 from the tax-free lump sums and savings account,</li>
<li>the ISA,</li>
<li>the tax-free lump sums,</li>
<li>the private pensions,</li>
<li>the savings account,</li>
<li>the general investment account.</li>
</ol>
<p>Outstanding amounts are withdrawn in that order until the needed quantity has been satisfied. By altering this sequence you can choose to exhaust pensions first, leaving saving and tax-free lump sums, or vice versa, or some other strategy.</p>
</section>
<section id="tax" class="level3">
<h3 class="anchored" data-anchor-id="tax">Tax</h3>
<p>Tax is paid at the end of each year by examining the amount drawn from each source and calculating the tax due on it. The tax is paid by visiting, in order, each of the sources in the TaxPaymentSequence field and making withdrawals from them until the tax amount is paid. If the tax payment sequence contains a taxable source then more tax may be incurred in drawing funds from it, in which case the unpaid tax is added to the needed amount for the following year.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode go code-with-copy"><code class="sourceCode go"><span id="cb8-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// A TaxAccount records the amount of a money on which tax has already been calculated.</span></span>
<span id="cb8-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// and also the calculated total amount of tax due on that amount.</span></span>
<span id="cb8-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">type</span> TaxAccount <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb8-4">    Name        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">string</span></span>
<span id="cb8-5">    regime      TaxRegime</span>
<span id="cb8-6">    taxedamount <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int64</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// The amount of money on which tax has already been calculated.</span></span>
<span id="cb8-7">    tax         <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int64</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// The total amount of tax that has been calculated to be due on that amount.</span></span>
<span id="cb8-8"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>The taxed amount and the tax due values are reset in a tax account at the start of each year.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode go code-with-copy"><code class="sourceCode go"><span id="cb9-1">taxAccounts <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">map</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[*</span>drawdown<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Source<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]*</span>drawdown<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>TaxAccount<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb9-2">    is_state_pension_1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> incomeTaxAccount1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb9-3">    is_state_pension_2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> incomeTaxAccount2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb9-4">    is_pension_1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span>       incomeTaxAccount1<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb9-5">    is_pension_2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span>       incomeTaxAccount2<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb9-6">    is_gia<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span>             capitalGainsTaxAccount<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb9-7"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>A TaxAccount may be shared by more than one source. For example, all sources which are subject to income tax. At the end of each year, the set of source withdrawals are examined to calculate the tax due in each of the tax accounts.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode go code-with-copy"><code class="sourceCode go"><span id="cb10-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// TaxRegime describes the rates of tax that are charged on increasing amounts.</span></span>
<span id="cb10-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Commonly the first RateBound in the slice might represents a tax-free allowance (i.e. its rate is zero).</span></span>
<span id="cb10-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">type</span> TaxRegime <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb10-4">    Rates <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span>RateBound</span>
<span id="cb10-5"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb10-6"></span>
<span id="cb10-7"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// RateBound contains a rate and an upper bound on the amount for which the rate applies.</span></span>
<span id="cb10-8"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// A slice of RateBound is used to describe a tax regime.</span></span>
<span id="cb10-9"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// In such a slice, subsequent upper values must be strictly increasing.</span></span>
<span id="cb10-10"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Rates are represented as a decimal percentage. For example, 10.1 for 10.1%.</span></span>
<span id="cb10-11"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">type</span> RateBound <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb10-12">    upper <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int64</span></span>
<span id="cb10-13">    rate  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">float64</span></span>
<span id="cb10-14"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>A TaxRegime defines the ranges and rates that are associated with a TaxAccount. For example, the following might define an income tax regime:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode go code-with-copy"><code class="sourceCode go"><span id="cb11-1">incomeTaxRegime <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> drawdown<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>NewTaxRegime<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">([]</span>drawdown<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>RateBound<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb11-2">        drawdown<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>NewRateBound<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12540</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span></span>
<span id="cb11-3">        drawdown<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>NewRateBound<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">50270</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">20.0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span></span>
<span id="cb11-4">        drawdown<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>NewRateBound<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">125140</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">40.0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span></span>
<span id="cb11-5">        drawdown<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>NewRateBound<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>drawdown<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>HighUpperBound<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">45.0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span></span>
<span id="cb11-6">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">})</span></span></code></pre></div></div>
<p>In this regime the first £12,540 of income would be tax free, the next £37,730 (= £50,270 - £12,540) would be taxed at 20%, the next £74,870 (= £125,140 - £50,270) would be taxed at 40%, and any amount above above that would be taxed at the 45% rate.</p>
</section>
<section id="actions" class="level3">
<h3 class="anchored" data-anchor-id="actions">Actions</h3>
<p>Actions are performed at the start of the year after the sources and tax accounts have been initialised and before any withdrawals are made.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode go code-with-copy"><code class="sourceCode go"><span id="cb12-1">actions <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">func</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>year <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> need <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int64</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> s <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>drawdown<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>DrawScenario<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb12-2">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">func</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>year <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> need <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int64</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> s <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>drawdown<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>DrawScenario<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb12-3">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">//fmt.Println("year", year, "need", need)</span></span>
<span id="cb12-4">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb12-5">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">func</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>year <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> need <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int64</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> s <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>drawdown<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>DrawScenario<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb12-6">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Every year make the maximum annual ISA contribution from the savings accounts.</span></span>
<span id="cb12-7">        drawdown<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Transfer<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(&amp;</span>annualMaximumIsaContribution<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> is_isa<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> is_savings<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> is_pension_1_tfls<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> is_pension_2_tfls<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb12-8">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb12-9"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>An action is a function that is called with three arguments: the year (starting at 0), the amount of money that needs to be withdrawn from the sources in the year (this includes an inflation adjusted increment from the previous year and any unpaid tax from the previous year), and the information in the DrawScenario.</p>
<p>In the example code above an action has been created as a convenient place to include debugging information and also to invoke a function to transfer an amount of money into an ISA account from a savings account, or if no saving are left, from one of the tax-free lump sum accounts.</p>
</section>
<section id="inflation-linked-variables" class="level3">
<h3 class="anchored" data-anchor-id="inflation-linked-variables">Inflation-linked Variables</h3>
<p>The DrawScenario InflationLinkedVariables slice contains pointers to a number of variables whose value is automatically incremented at the end of each year by the rate of inflation. In the example actions above the annualMaximumIsaContribution is such an inflation-linked variable.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode go code-with-copy"><code class="sourceCode go"><span id="cb13-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Inflation linked variables</span></span>
<span id="cb13-2">incomeTaxAllowance <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> incomeTaxRegime<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>TaxFreeAllowance<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span></span>
<span id="cb13-3">capitalGainsTaxAllowance <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> capitalGainsTaxRegime<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>TaxFreeAllowance<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span></span>
<span id="cb13-4">annualMaximumIsaContribution <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int64</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">20000</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb13-5">v1000 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int64</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1000</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb13-6"></span>
<span id="cb13-7">allInflationLinkedVariables <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]*</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int64</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb13-8">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>annualMaximumIsaContribution<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb13-9">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>incomeTaxAllowance<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb13-10">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>capitalGainsTaxAllowance<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb13-11">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>v1000<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb13-12"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>You can see from the code above how we maintain our estimate of the likely value of the maximum ISA contribution that can be made each year by increasing its value in line with inflation. Similarly, in the example, v1000 is an inflation linked amount that is equivalent to £1,000 in year 0.</p>
</section>
<section id="draw-rates" class="level3">
<h3 class="anchored" data-anchor-id="draw-rates">Draw Rates</h3>
<p>The DrawRates are those input rates that determine how investments and savings are expected to grow, what the expected annual inflation rate and the annual platform charge are and how quickly to increase the TaxRegime tax bands.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode go code-with-copy"><code class="sourceCode go"><span id="cb14-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">type</span> DrawRates <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb14-2">    InvestmentGrowthRate     <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">float64</span></span>
<span id="cb14-3">    SavingsGrowthRate        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">float64</span></span>
<span id="cb14-4">    AnnualInflationRate      <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">float64</span></span>
<span id="cb14-5">    PlatformChargeRate       <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">float64</span></span>
<span id="cb14-6">    TaxBandAnnualPctIncrease <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">float64</span></span>
<span id="cb14-7"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>Investment account and savings accounts are initialised using the investment and savings growth rates:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb15" style="background: #f1f3f5;"><pre class="sourceCode go code-with-copy"><code class="sourceCode go"><span id="cb15-1">    is_savings <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> drawdown<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>NewSavingsAccount<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Savings"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> SavingsInitialBalance<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Rates<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>SavingsGrowthRate<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb15-2">    is_isa <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> drawdown<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>NewInvestmentAccount<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ISA"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> IsaInitialBalance<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Rates<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>InvestmentGrowthRate<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb15-3"></span>
<span id="cb15-4">    is_pension_1 <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> drawdown<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>NewInvestmentAccount<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Pension 1"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.75</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>Pension1InitialBalance<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Rates<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>InvestmentGrowthRate<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb15-5">    is_pension_1_tfls <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> drawdown<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>NewSavingsAccount<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"TFLS 1"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.25</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>Pension1InitialBalance<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Rates<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>SavingsGrowthRate<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span></code></pre></div></div>
<p>At the start of the year the amount of money needed is scaled up from the initial year 0 amount by the annual inflation rate and at the end of the year the inflation linked variable are also scaled in the same way.</p>
<p>At the start of the year the platform charge is calculated by adding up the total balance from all of the sources and multiplying it by the PlatformChargeRate. This is then added to the money needed amount in addition to any unpaid tax left over from the previous year to give an amount that needs to be withdrawn from the sources in the year.</p>
<p>At the end of the year the tax regime upper bounds are scaled up by the TaxBandAnnualPctIncrease percentage.</p>
</section>
</section>
<section id="summary" class="level2">
<h2 class="anchored" data-anchor-id="summary">Summary</h2>
<p>There are some obvious limitations to the drawdown model that could be improved upon:</p>
<ol type="1">
<li>It is almost certainly unreasonable to be able to predict any of the rates with a degree of accuracy over a 30 or 40 year period - especially the rate of inflation.</li>
<li>It would be nice to move the configuration of the drawdown strategy out of code and into a textual format (such as JSON) so that the tool could more readily compare multiple strategies as well as multiple rates.</li>
</ol>
<p>A partial solution to the first limitation is to use the summary mode to examine the effect of a range of values for a given rate. A mitigating factor for the second limitation is that, assuming you are a Go programmer, it is easy and quick to make a change to the strategy by editing the code.</p>
<p>Nevertheless, the tool can be used to get a feel for how comfortably (or not) your desired annual withdrawal can be satisfied from the set of investments and savings that you have at retirement. And, by making changes to the order of withdrawal, by altering the draw sequence, you can experiment with different strategies.</p>
</section>
<section id="source-code" class="level2">
<h2 class="anchored" data-anchor-id="source-code">Source Code</h2>
<p>The Go code for Drawdown can be found here: <a href="https://github.com/Vextasy/Drawdown_Go">https://github.com/Vextasy/Drawdown_Go</a>.</p>
<p>The strategy used in the examples in this document can be found in the source file <code>scenario/simple.go</code>.</p>


</section>

 ]]></description>
  <category>Go</category>
  <category>Pension Drawdown</category>
  <guid>https://www.oldgang.net/notebooks/posts/drawdown_go/drawdown_go.html</guid>
  <pubDate>Thu, 21 Nov 2024 00:00:00 GMT</pubDate>
</item>
<item>
  <title>What’s On: Enhancing an AI with data from a local database</title>
  <dc:creator>John Bates</dc:creator>
  <link>https://www.oldgang.net/notebooks/posts/whats_on/whats_on.html</link>
  <description><![CDATA[ 




<p>What’s On is a simple Go command line program to interact with the Claude API (using <a href="https://github.com/liushuangls/go-anthropic">go-anthropic</a>) to return a number of TV programme viewing suggestions given a statement of desire. The purpose of the program is to allow me to experiment with Claude embedding, its use of tools, and its XML input and output techniques. And the purpose of this notebook is to remind me how it works.</p>
<p>The program uses a local database of TV schedules which Claude requests access to through its ‘tool’ mechanism. To avoid having to recreate the database daily, dates in the database are automatically shifted to appear as if they start from the current date.</p>
<p>The Go code for What’s On can be found here: <a href="https://github.com/Vextasy/WhatsOn">https://github.com/Vextasy/WhatsOn</a>.</p>
<p><strong>Usage</strong></p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb1-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">./whatson</span> <span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">[-</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">d</span><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">]</span> <span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">[-</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">v</span><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">]</span> statement of desire ...</span></code></pre></div></div>
<p>The -d flag causes the program to follow the list of suggestions with a description of each program. Claude, being an AI, can of course make changes to those descriptions and this can be a way in which you can gain some insight into why it has made a suggestion.</p>
<p>For example:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb2-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">./whatson</span> I would like to watch programmes about archaeology that are on in the next couple of weeks.</span>
<span id="cb2-2"></span>
<span id="cb2-3"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">-</span> Sun 2024-07-07 at 20:00: Digging for Britain on BBC4</span>
<span id="cb2-4"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">-</span> Sun 2024-07-14 at 20:00: Digging for Britain on BBC4</span></code></pre></div></div>
<p>An explanation of Claude’s thinking can be viewed by providing the -v flag.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb3-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">./whatson</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-v</span> I would like to watch programmes about archaeology that are on in the next couple of weeks.</span>
<span id="cb3-2"></span>
<span id="cb3-3"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">To</span> provide appropriate TV programme suggestions about archaeology for the next couple of weeks, I<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'ll need to use the get_tv_programmes function. Let'</span>s gather the necessary information:</span>
<span id="cb3-4"></span>
<span id="cb3-5"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">1.</span> The current date is 2024-06-30 <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Sunday</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">.</span></span>
<span id="cb3-6"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">2.</span> The user wants programmes about archaeology in the next couple of weeks.</span>
<span id="cb3-7"></span>
<span id="cb3-8"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">I</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'ll set the date range from today (2024-06-30) to two weeks later (2024-07-14) to cover the requested period.</span></span>
<span id="cb3-9"></span>
<span id="cb3-10"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">Using the tool date range: 2024-06-30 to 2024-07-14</span></span>
<span id="cb3-11"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">- Sun 2024-07-07 at 20:00: Digging for Britain on BBC4</span></span>
<span id="cb3-12"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">- Sun 2024-07-14 at 20:00: Digging for Britain on BBC4</span></span></code></pre></div></div>
<p>A description of each programme can be obtained with the -d flag.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb4-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">./whatson</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Show me suggestions for programmes that are related to animals and are on in the next couple of weeks."</span></span>
<span id="cb4-2"></span>
<span id="cb4-3"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">-</span> Sun 2024-07-02 at 18:00: Countryfile on BBC1</span>
<span id="cb4-4"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">-</span> Sun 2024-07-02 at 20:00: The Great British Bake Off on Channel 4</span>
<span id="cb4-5"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">-</span> Fri 2024-07-05 at 20:00: The Secret Life of the Zoo on BBC4</span>
<span id="cb4-6"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">-</span> Mon 2024-07-08 at 22:30: The Sky at Night on BBC4</span>
<span id="cb4-7"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">-</span> Sun 2024-07-14 at 20:00: Digging for Britain on BBC4</span></code></pre></div></div>
<p>Asking Claude to explain itself through the descriptions can be insightful.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb5-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">./whatson</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-d</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Show me suggestions for programmes that are related to animals and are on in the next couple of weeks.  Update the programme description to show how it is related to animals."</span></span>
<span id="cb5-2"></span>
<span id="cb5-3"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">-</span> Sun 2024-07-02 at 18:00: Countryfile on BBC1</span>
<span id="cb5-4"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">-</span> Sun 2024-07-02 at 20:00: The Great British Bake Off on Channel 4</span>
<span id="cb5-5"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">-</span> Fri 2024-07-05 at 20:00: The Secret Life of the Zoo on BBC4</span>
<span id="cb5-6"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">-</span> Mon 2024-07-08 at 22:30: The Sky at Night on BBC4</span>
<span id="cb5-7"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">-</span> Sun 2024-07-14 at 20:00: Digging for Britain on BBC4</span>
<span id="cb5-8"></span>
<span id="cb5-9"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Descriptions:</span></span>
<span id="cb5-10"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">-</span> Countryfile : Exploring rural issues and celebrating the beauty of the British countryside, with segments featuring farm animals</span>
<span id="cb5-11"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">-</span> The Great British Bake Off : Amateur bakers compete in a series of challenging baking tasks using ingredients like eggs and dairy from animals.</span>
<span id="cb5-12"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">-</span> The Secret Life of the Zoo : Behind-the-scenes look at the lives of various animals and their keepers at Chester Zoo, providing intimate insights into animal behavior, care, and conservation efforts.</span>
<span id="cb5-13"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">-</span> The Sky at Night : While primarily about astronomy, this episode may explore the impact of space exploration on animal research, such as studying the effects of microgravity on various species or discussing animals used in early space missions.</span>
<span id="cb5-14"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">-</span> Digging for Britain : This archaeology program often uncovers animal remains and artifacts related to historical human-animal interactions, providing insights into ancient fauna and our evolving relationships with animals throughout British history.</span></code></pre></div></div>
<p>Apologies to any vegetarians, but the explanation that Claude gives for including the Great British Bake Off in the list of programmes related to animals is a lovely example of how tricky it is to ensure that your aims and what the AI takes to be your aims are aligned.</p>
<section id="techniques" class="level2">
<h2 class="anchored" data-anchor-id="techniques">Techniques</h2>
<p>In addition to using the very nice interface that <a href="https://github.com/liushuangls/go-anthropic">go-anthropic</a> provides to allow interaction with Claude using Go, this application makes use of three techniques that are described in the Claude documentation <a href="https://docs.anthropic.com/en/docs/welcome">here</a>:</p>
<ol type="1">
<li>Embedding</li>
<li>Tool Use</li>
<li>XML Tags</li>
</ol>
</section>
<section id="embedding" class="level2">
<h2 class="anchored" data-anchor-id="embedding">Embedding</h2>
<p>The Claude documentation describes embeddings as <a href="https://docs.anthropic.com/en/docs/build-with-claude/embeddings">“numerical representations of text that enable measuring semantic similarity”</a>. So, strictly, in this application we don’t do proper embedding. But I was keen to see how embeddings could be used to incorporate data from a local database into the interaction with an AI and the technique that is used here is similar to what would be done when performing proper embedding.</p>
<p>An embedding model can be trained on a local dataset and will return documents that most closely match a given query. These documents can then be passed to Claude as part of the prompt generation process in order that Claude might use the information that they contain to help answer the original query.</p>
<p>Claude doesn’t have its own embedding model but, rather, works with an external embedding mechanism. Currently they recommend using Voyage AI.</p>
<p>For this simple application, our local database is a collection of TV programme schedules. Each programme has a name, a channel, a date, a time and a description. We encourage Claude to ask for details of TV programmes that are scheduled to be broadcast between a given range of dates. We could equally well have asked Claude to request programmes based on a more complex query, such as by genre or subject matter but then we would need to consider using a proper embedding database in order to provide a good response. So by keeping the local database queries to just a range of dates we can handle selection from the database with a very basic model.</p>
</section>
<section id="tool-use" class="level2">
<h2 class="anchored" data-anchor-id="tool-use">Tool Use</h2>
<p>Claude allows user-defined tools to be described as part of a request. A tool can be thought of as a function that Claude might call to request certain information. As well as giving the tool a name, and a description that describes to Claude what the tool can be used for and how to use it, it also enumerates any parameters that Claude should supply when calling the tool.</p>
<p>If Claude thinks that it could benefit from using a particular tool it will return a response to its initial query containing a request to call the tool and will supply the necessary tool parameters. A request to make use of a tool will appear in a response with a <code>content.Type == anthropic.MessagesContentTypeToolUse</code>. And the parameters can be obtained from the <code>content.MessagecontentToolUse</code> field.</p>
<p>In an application making real use of an embedding database we might ask Claude to supply a query that could be made to the database to return a set of documents with which to enhance the subsequent request to Claude. In our rather simple example the tool use request will contain the date range between which Claude would like to know about programmes from our TV database.</p>
<p>The tools available to Claude are described in the Tools section of the initial message request. Our <code>get_tv_programmes</code> tool is described like this:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode go code-with-copy"><code class="sourceCode go"><span id="cb6-1">Tools<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span>anthropic<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>ToolDefinition<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-2">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-3">        Name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"get_tv_programmes"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb6-4">        Description<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">`Gets information about the TV programmes that will be aired between the given from_date and to_date inclusive.</span></span>
<span id="cb6-5"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">            If to_date is not provided, it will default to the same date as the from_date.</span></span>
<span id="cb6-6"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">            It should be used when the user asks about TV programmes and we want to know which programs will be shown in the near future including today.</span></span>
<span id="cb6-7"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">            Programme information will be returned in XML tags with the following format:</span></span>
<span id="cb6-8"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">                &lt;Programmes&gt;</span></span>
<span id="cb6-9"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">                    &lt;Programme&gt;</span></span>
<span id="cb6-10"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">                        &lt;Channel&gt;Channel Name&lt;/Channel&gt;</span></span>
<span id="cb6-11"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">                        &lt;Name&gt;Programme Name&lt;/Name&gt;</span></span>
<span id="cb6-12"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">                        &lt;Date&gt;YYYY-MM-DD&lt;/Date&gt;</span></span>
<span id="cb6-13"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">                        &lt;Time&gt;HH:MM&lt;/Time&gt;</span></span>
<span id="cb6-14"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">                        &lt;Description&gt;Programme Description&lt;/Description&gt;</span></span>
<span id="cb6-15"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">                    &lt;/Programme&gt;</span></span>
<span id="cb6-16"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">                &lt;/Programmes&gt;</span></span>
<span id="cb6-17"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">            The outer level &lt;Programmes&gt;&lt;/Programmes&gt; tag will be omitted if the result is empty,</span></span>
<span id="cb6-18"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">            but will otherwise contain one or more &lt;Programme&gt;&lt;/Programme&gt; tags.</span></span>
<span id="cb6-19"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">            The &lt;Location&gt;&lt;/Location&gt; tag contains the TV channel on which the program will be shown.</span></span>
<span id="cb6-20"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">            `</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb6-21">        InputSchema<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> jsonschema<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Definition<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-22">            Type<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> jsonschema<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Object<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb6-23">            Properties<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">map</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">string</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span>jsonschema<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Definition<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-24">                <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"from_date"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-25">                    Type<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span>        jsonschema<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>String<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb6-26">                    Description<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"The start date of the TV programmes search. Format: YYYY-MM-DD"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb6-27">                <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb6-28">                <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"to_date"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-29">                    Type<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span>        jsonschema<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>String<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb6-30">                    Description<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"The end date of the TV programmes search. Format: YYYY-MM-DD"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb6-31">                <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb6-32">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb6-33">            Required<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">string</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"from_date"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb6-34">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb6-35">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}},</span></span></code></pre></div></div>
<p>It makes it quite clear which parameters will be required and the format in which information will be returned from the tool.</p>
</section>
<section id="xml-tags" class="level2">
<h2 class="anchored" data-anchor-id="xml-tags">XML Tags</h2>
<p>Anthropic suggest that good use is made of XML tags to supply data to Claude or to return data from Claude. This is achieved by being explicit about the format of such input or output data in the prompt that is constructed to send to Claude.</p>
<p>In our case we construct the following initial prompt:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode go code-with-copy"><code class="sourceCode go"><span id="cb7-1">You are given information about TV programmes enclosed between <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Programmes<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&lt;/</span>Programmes<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> tags<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span></span>
<span id="cb7-2">The date today is <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">` + time.Now().Format("2006-01-02") + `</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> a <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">` + time.Now().Weekday().String() + `</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span></span>
<span id="cb7-3">You are an expert at suggesting TV programmes<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span></span>
<span id="cb7-4">The user would like to have some suggestions about what TV programmes to watch but has the following strict request<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:&lt;</span>Request<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">` + desire + `</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;/</span>Request<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;.</span></span>
<span id="cb7-5">Your task is to provide a list of programme suggestions in XML format using the following tag structure <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> each selection<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span></span>
<span id="cb7-6"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Suggestion<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&lt;</span>Channel<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span>Channel Name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;/</span>Channel<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&lt;</span>Name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span>Programme Name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;/</span>Name <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Date<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span>YYYY<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>MM<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>DD<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;/</span>Date<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&lt;</span>Time<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span>HH<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span>MM<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;/</span>Time<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&lt;</span>Description<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span>Programme Description<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;/</span>Description<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&lt;/</span>Suggestion<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb7-7">Wrap the list of <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Suggestion<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&lt;/</span>Suggestion<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> tags in a <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Suggestions<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&lt;/</span>Suggestions<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> tag<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span></span>
<span id="cb7-8">Do not output <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">any</span> other information either before or after the <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Suggestions<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&lt;/</span>Suggestions<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> tags<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span></span>
<span id="cb7-9">If the user does not request that programs begin within a particular date <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">range</span> then use a <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">range</span> that begins today and ends <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> week later<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span></span>
<span id="cb7-10">Return at most <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span> suggestions<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span></span>
<span id="cb7-11">If you have no suggestions then <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> the <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>Suggestions<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&lt;/</span>Suggestions<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> tags with no content<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span></span>
<span id="cb7-12">Before answering re<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span>check that all of the user<span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'s requests have been met.</span></span>
<span id="cb7-13">If you are not sure that a particular suggestion satisfies the user<span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">'s Requests then do not return that suggestion.</span></span>
<span id="cb7-14">If the user has requested programmes on a particular day of the week or days of the week check that only programmes on those days are returned<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span></span>
<span id="cb7-15"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">`</span></span></code></pre></div></div>
<p>The prompt explains to Claude that it can find programme schedule information between <code>&lt;Programmes&gt;</code> and <code>&lt;/Programmes&gt;</code> tags and that it should return information between <code>&lt;Suggestions&gt;</code> and <code>&lt;/Suggestions&gt;</code> tags. This makes it easy for Claude to read the results of its use of a tool and for us to read the output of the final interaction with Claude.</p>
</section>
<section id="constructing-the-tv-database" class="level2">
<h2 class="anchored" data-anchor-id="constructing-the-tv-database">Constructing the TV Database</h2>
<p>In order to construct the database of TV schedules we made use of Claude to generate some fictitious TV programmes and to assign them a schedule. The prompt needed to perform that task was:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode xml code-with-copy"><code class="sourceCode xml"><span id="cb8-1">I would like you to generate some fictitious TV listings data for me.</span>
<span id="cb8-2"></span>
<span id="cb8-3">The data will be in XML format using the following tags:</span>
<span id="cb8-4"></span>
<span id="cb8-5">&lt;<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Programmes</span>&gt;</span>
<span id="cb8-6">    &lt;<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Programme</span>&gt;</span>
<span id="cb8-7">        &lt;<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Channel</span>&gt;Channel Name&lt;/<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Channel</span>&gt;</span>
<span id="cb8-8">        &lt;<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Name</span>&gt;Programme Name&lt;/<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Name</span>&gt;</span>
<span id="cb8-9">        &lt;<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Date</span>&gt;YYYY-MM-DD&lt;/<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Date</span>&gt;</span>
<span id="cb8-10">        &lt;<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Time</span>&gt;HH:MM&lt;/<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Time</span>&gt;</span>
<span id="cb8-11">        &lt;<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Description</span>&gt;Programme Description&lt;/<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Description</span>&gt;</span>
<span id="cb8-12">    &lt;/<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Programme</span>&gt;</span>
<span id="cb8-13">&lt;<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Programmes</span>&gt;</span>
<span id="cb8-14"></span>
<span id="cb8-15">Each programme is described by the contents of a pair of &lt;<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Programme</span>&gt;&lt;/<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Programme</span>&gt; tags.</span>
<span id="cb8-16"></span>
<span id="cb8-17">Valid values for Channel are: BBC1, BBC2, BBC3, BBC4, ITV, Channel 4.</span>
<span id="cb8-18"></span>
<span id="cb8-19">Here are some examples:</span>
<span id="cb8-20"></span>
<span id="cb8-21">&lt;<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Programmes</span>&gt;</span>
<span id="cb8-22">    &lt;<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Programme</span>&gt;</span>
<span id="cb8-23">        &lt;<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Channel</span>&gt;BBC1&lt;/<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Channel</span>&gt;</span>
<span id="cb8-24">        &lt;<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Name</span>&gt;The Night of the Hunter&lt;/<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Name</span>&gt;</span>
<span id="cb8-25">        &lt;<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Date</span>&gt;2024-06-20&lt;/<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Date</span>&gt;</span>
<span id="cb8-26">        &lt;<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Time</span>&gt;18:00&lt;/<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Time</span>&gt;</span>
<span id="cb8-27">        &lt;<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Description</span>&gt;A film about the life of a hunter and his family who travel from location to location in search of food.&lt;/<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Description</span>&gt;</span>
<span id="cb8-28">    &lt;/<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Programme</span>&gt;</span>
<span id="cb8-29">    &lt;<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Programme</span>&gt;</span>
<span id="cb8-30">        &lt;<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Channel</span>&gt;BBC2&lt;/<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Channel</span>&gt;</span>
<span id="cb8-31">        &lt;<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Name</span>&gt;Would I Lie to You?&lt;/<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Name</span>&gt;</span>
<span id="cb8-32">        &lt;<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Date</span>&gt;2024-06-20&lt;/<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Date</span>&gt;</span>
<span id="cb8-33">        &lt;<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Time</span>&gt;19:00&lt;/<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Time</span>&gt;</span>
<span id="cb8-34">        &lt;<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Description</span>&gt;A comedy quiz in which contestants have to determine if the others are lying or telling the truth.&lt;/<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Description</span>&gt;</span>
<span id="cb8-35">    &lt;/<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Programme</span>&gt;</span>
<span id="cb8-36">    &lt;<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Programme</span>&gt;</span>
<span id="cb8-37">        &lt;<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Channel</span>&gt;BBC4&lt;/<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Channel</span>&gt;</span>
<span id="cb8-38">        &lt;<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Name</span>&gt;Easter Island Origins&lt;/<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Name</span>&gt;</span>
<span id="cb8-39">        &lt;<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Date</span>&gt;2024-06-20&lt;/<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Date</span>&gt;</span>
<span id="cb8-40">        &lt;<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Time</span>&gt;19:00&lt;/<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Time</span>&gt;</span>
<span id="cb8-41">        &lt;<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Description</span>&gt;Documentary exploring how new evidence is challenging everything we thought we knew about Easter Island and the nearly 900 giant stone statues scattered across this remote Pacific island. They are some of the most famous and mysterious monuments on the planet. Nearly 900 giant stone heads scattered across a remote island in the middle of the Pacific. Now, brand new evidence is challenging everything we thought we knew about Easter Island’s awe-inspiring statues – and those who made them. Drawing on the latest science, this authoritative documentary radically rewrites the story of Easter Island.&lt;/<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Description</span>&gt;</span>
<span id="cb8-42">    &lt;/<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Programme</span>&gt;</span>
<span id="cb8-43">    &lt;<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Programme</span>&gt;</span>
<span id="cb8-44">        &lt;<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Channel</span>&gt;BBC2&lt;/<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Channel</span>&gt;</span>
<span id="cb8-45">        &lt;<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Name</span>&gt;Elsa the Lioness&lt;/<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Name</span>&gt;</span>
<span id="cb8-46">        &lt;<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Date</span>&gt;2024-06-21&lt;/<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Date</span>&gt;</span>
<span id="cb8-47">        &lt;<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Time</span>&gt;18:00&lt;/<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Time</span>&gt;</span>
<span id="cb8-48">        &lt;<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Description</span>&gt;First transmitted in 1961, David Attenborough visits Joy and George Adamson in Kenya and meets Elsa the lioness and her cubs shortly before Elsa's death. First transmitted in 1961, David Attenborough travels to Meru National Park in Kenya to visit Joy and George Adamson and meet Elsa the lioness and her cubs shortly before Elsa's death.&lt;/<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Description</span>&gt;</span>
<span id="cb8-49">    &lt;<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Programme</span>&gt;</span>
<span id="cb8-50">&lt;<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">Programmes</span>&gt;</span>
<span id="cb8-51"></span>
<span id="cb8-52">I would like you to generate data for about 70 programmes with dates ranging from 2024-06-21 to 2024-06-30</span>
<span id="cb8-53">and with starting times on the hour or at 15, 30 or 45 minutes past the hours.</span>
<span id="cb8-54">Make the programme names and descriptions as realistic as possible.</span>
<span id="cb8-55">The genres of some of the programmes should be film.</span></code></pre></div></div>
<p>Such a simple thing saved a lot of programming time. As often seems to be the case when working with Claude, I was surprised at some of the detail in the fictitious schedule. The full database is shown in the GitHub repository in the file <code>TvDb.xml</code>. But, for example, the programme “Good Morning Britain” has been schedule for 06:30am and “The Sky at Night” for 10:30pm.</p>
</section>
<section id="final-thoughts" class="level2">
<h2 class="anchored" data-anchor-id="final-thoughts">Final Thoughts</h2>
<p>Even though this is a very simple application it made it more clear to me how an AI such as Claude could be programmed to make use of specific locally stored information and combine it with the language, and wider knowledge, that the AI has, resulting in a useful tool.</p>
<p>Being able to precisely describe the expected inputs and outputs makes it easier to work with Claude from a traditional programming language.</p>
<p>AIs, such as Claude, can often be used to help construct parts of the program. In our case it built our TV database, but it could also have been used to write some of the code used to interact with the SDK.</p>
<p>It is worth stressing in the prompts the importance of checking the results before returning them, and the <code>-v</code> flag to get Claude to explain its workings was a useful addition.</p>


</section>

 ]]></description>
  <category>AI</category>
  <category>Claude</category>
  <category>Go</category>
  <guid>https://www.oldgang.net/notebooks/posts/whats_on/whats_on.html</guid>
  <pubDate>Wed, 10 Jul 2024 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Goal: Go Array Language</title>
  <dc:creator>John Bates</dc:creator>
  <link>https://www.oldgang.net/notebooks/posts/goal/goal.html</link>
  <description><![CDATA[ 




<p>In previous notebooks I wrote about my experiences with <a href="../../../notebooks/posts/the_lure_of_j/the_lure_of_j.html">J</a> and <a href="../../../notebooks/posts/ivy/ivy.html">Ivy</a>, both APL-like languages. <a href="https://anaseto.codeberg.page/goal-docs/index.html">Goal</a>, like Ivy, is also written in Go. Unlike Ivy, Goal is based on the the <a href="https://en.wikipedia.org/wiki/K_(programming_language)">K programming language</a> which is itself a variant of APL.</p>
<p>Goal builds on the K language by both extending and simplifying. Extensions include:</p>
<ul>
<li>Strings in goal are Unicode aware and are one of the atomic types of the language.</li>
<li>Many verbs have specific behaviour for strings.</li>
<li>In addition to regular expression string matching the language supports a flexible string formatting and interpolation syntax.</li>
<li>An atomic error type can be matched and handled with a conditional.</li>
<li>Goal can be embedded in a Go program and extended by Go code.</li>
</ul>
<p>The differences between Goal and K are documented <a href="https://anaseto.codeberg.page/goal-docs/chap-from-k.html">here</a>.</p>
<p>The main <a href="https://anaseto.codeberg.page/goal-docs/chap-FAQ.html#influences">influences</a> of Goal are the <a href="https://codeberg.org/ngn/k">ngn/k</a> dialect of K and <a href="https://mlochbaum.github.io/BQN/index.html">BQN</a>.</p>
<p>Once you start to look at these APL-like languages you discover what a web of variants exist. The best place to discover them is to browse the <a href="https://aplwiki.com/wiki/List_of_open-source_array_languages">APL Wiki</a>, or the <a href="https://k.miraheze.org/wiki/Running_K#Table_of_Implementations">K Wiki</a>.</p>
<p>A simplified view of the APL variant genealogy can be derived from the data <a href="https://github.com/abrudz/genealogy/blob/main/reduced.txt">here</a>.</p>
<p>The diagram below uses a subset of this data to show the relationships between a number of popular APL variants. An arrow from A to B indicates that variant B inherits some of its properties from variant A.</p>
<div class="cell" data-layout-align="default">
<div class="cell-output-display">
<div>
<p></p><figure class="figure"><p></p>
<div>
<pre class="mermaid mermaid-js">flowchart TB
APL(APL: A programming language) --&gt; APL360(APL360)
APLUS(A+) --&gt; BQN(BQN)
APLUS --&gt; K(K)
APL360 --&gt; APLPLUS(APL PLUS)
APL360 --&gt; J(J)
APL360 --&gt; MATLAB(MATLAB)
APL360 --&gt; Mathematica(Mathematica)
APL360 --&gt; R(R)
APLPLUS --&gt; NARS(NARS)
APLPLUS --&gt; SHARP(SHARP APL)
BQN --&gt; Goal(Goal)
J --&gt; BQN
J --&gt; Dyalog(Dyalog APL)
Dyalog --&gt; BQN
K --&gt; Q(Q)
K --&gt; Klong(Klong)
K --&gt; NGN(ngn/k)
K --&gt; oK(oK)
NGN --&gt; Goal
Mathematica --&gt; Julia(Julia)
MATLAB --&gt; Julia
NARS --&gt; Ivy(Ivy)
R --&gt; Julia
SHARP --&gt; J
SHARP --&gt; Dyalog
SHARP --&gt; APLUS

style Goal fill:lightgreen
style Ivy fill:lightgreen
style J fill:lightgreen
style K fill:lightgreen
</pre>
</div>
<p></p></figure><p></p>
</div>
</div>
</div>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Note
</div>
</div>
<div class="callout-body-container callout-body">
<p>The source code for Goal is available on Codeberg (<a href="https://codeberg.org/anaseto/goal">here</a>) and documentation can be found <a href="https://anaseto.codeberg.page/goal-docs/index.html">here</a>.</p>
</div>
</div>
<p>I was interested to see how Goal would cope with my simple array manipulation task that I had described in my <a href="../../../notebooks/posts/the_lure_of_j/the_lure_of_j.html">lure of J</a> and <a href="../../../notebooks/posts/ivy/ivy.html">Ivy</a> notebooks. This notebook is a record of how that task can be performed using Goal.</p>
<section id="simple-array-manipulation-task" class="level3">
<h3 class="anchored" data-anchor-id="simple-array-manipulation-task">Simple Array Manipulation Task</h3>
<p>That task involved the following steps - their implementation in Goal is given below:</p>
<ol type="1">
<li><p>Write a function, <code>outArray</code> that, given a string title and an array of integers as its two parameters, outputs that array as a comma-separated list, preceded by the title, a count of the number of integers in square-brackets and a colon. So, called with the parameters <code>"Initial"</code> and <code>1 2 3 4</code>, it would return:</p>
<p><code>Initial [4]: 1, 2, 3, 4</code></p></li>
<li><p>Assign a small array of ints, say, the array: <code>31 5 7 6 3 2 8</code> to the variable <code>ints</code>.</p></li>
<li><p>Use the <code>outArray</code> function to output the <code>ints</code> array with the title “Initial”.</p></li>
<li><p>Create a new array, <code>sortedInts</code>, from the original <code>ints</code> which contains the elements but sorted into ascending order, and output it with the outArray function using the title “Sorted”.</p></li>
<li><p>Create an array, <code>oddInts</code>, that contains just those ints from <code>sortedInts</code> that are odd and output it with the title “Odd”.</p></li>
<li><p>Create an array, <code>argvInts</code>, that has been read from the command line and output it with the title “argvInts”.</p></li>
<li><p>Create an array, <code>fileInts</code>, that has been read from a file on the filesystem that contains a single line of comma-separated integers and output it with the title “FileInts”.</p></li>
<li><p>Combine the <code>oddInts</code>, <code>argvInts</code>, and <code>fileInts</code> arrays into a single array, <code>combinedInts</code>, without duplicates and output it with the title “CombinedInts”.</p></li>
<li><p>Calculate the average of the numbers in the <code>combinedInts</code> array and store it in the scalar <code>average</code>.</p></li>
<li><p>Split the numbers in the <code>combinedInts</code> array into two distinct arrays, <code>higher</code> and <code>lower</code> such that <code>higher</code> contains those ints that are higher than the value in <code>average</code> and <code>lower</code> contains the remaining ints. Output both <code>higher</code> and <code>lower</code> with `outArray’.</p></li>
</ol>
<p>The Goal implementation is:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb1-1">outArray<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">{</span></span>
<span id="cb1-2">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[</span>title<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">;</span> ints<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">]</span></span>
<span id="cb1-3">    print <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"%</span>s<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[%</span>d]<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">%</span>s<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"$</span><span class="re">(</span>title<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">;</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">#</span>ints<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">;</span> csv <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span>ints<span class="re">)</span></span>
<span id="cb1-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">}</span></span>
<span id="cb1-5"></span>
<span id="cb1-6">ints<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">31</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span></span>
<span id="cb1-7">outArray<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">["</span>Initial<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">";</span> ints<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">]</span></span>
<span id="cb1-8"></span>
<span id="cb1-9">sortedInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> ints<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[&lt;</span>ints<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">]</span></span>
<span id="cb1-10">outArray<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">["</span>Sorted<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">";</span> sortedInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">]</span></span>
<span id="cb1-11"></span>
<span id="cb1-12">oddInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> sortedInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[&amp;</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">!</span>sortedInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">]</span></span>
<span id="cb1-13">outArray<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">["</span>Odd<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">";</span> oddInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">]</span></span>
<span id="cb1-14"></span>
<span id="cb1-15">argvInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"</span>i<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"$</span>'1_ARGS</span>
<span id="cb1-16">outArray<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">["</span>ArgvInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">";</span> argvInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">]</span></span>
<span id="cb1-17"></span>
<span id="cb1-18">fileInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">*"</span>i<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"$</span>csv 'read <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"./</span>fileints<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">.</span>csv<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"</span></span>
<span id="cb1-19">outArray<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">["</span>FileInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">";</span> fileInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">]</span></span>
<span id="cb1-20"></span>
<span id="cb1-21">combinedInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">?</span>oddInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> argvInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> fileInts</span>
<span id="cb1-22">outArray<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">["</span>CombinedInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">";</span> combinedInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">]</span></span>
<span id="cb1-23"></span>
<span id="cb1-24">average<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">{</span><span class="re">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">+/x</span><span class="re">)</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">%#x}</span> combinedInts</span>
<span id="cb1-25">say <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"</span>average<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">%</span>f<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"$</span>average</span>
<span id="cb1-26"></span>
<span id="cb1-27">higher<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">{x@&amp;x</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">&gt;</span> average<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">}</span>combinedInts</span>
<span id="cb1-28">outArray<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">["</span>Higher<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">";</span>higher<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">]</span></span>
<span id="cb1-29"></span>
<span id="cb1-30">lower<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">{x@&amp;~x</span> in higher<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">}[</span>combinedInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">]</span></span>
<span id="cb1-31">outArray<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">["</span>Lower<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">";</span>lower<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">]</span></span></code></pre></div></div>
<p>If we invoke goal with the arguments ‘2 3 4 5’ and if the current directory contains a CSV format file named “fileints.csv” containing the line: <code>5,55,25,15</code> we will see the following output.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb2-1">Initial<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>]<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">31</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span></span>
<span id="cb2-2">Sorted<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>]<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">31</span></span>
<span id="cb2-3">Odd<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>]<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">31</span></span>
<span id="cb2-4">ArgvInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>]<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span></span>
<span id="cb2-5">FileInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>]<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">55</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">25</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">15</span></span>
<span id="cb2-6">CombinedInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9</span>]<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">31</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">55</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">25</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">15</span></span>
<span id="cb2-7">average<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">16.333333</span></span>
<span id="cb2-8">Higher<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>]<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">31</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">55</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">25</span></span>
<span id="cb2-9">Lower<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>]<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">15</span></span></code></pre></div></div>
</section>
<section id="the-outarray-function" class="level3">
<h3 class="anchored" data-anchor-id="the-outarray-function">The OutArray Function</h3>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb3-1">outArray<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">{</span></span>
<span id="cb3-2">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[</span>title<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">;</span> ints<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">]</span></span>
<span id="cb3-3">    print <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"%</span>s<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[%</span>d]<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">%</span>s<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"$</span><span class="re">(</span>title<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">;</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">#</span>ints<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">;</span> csv <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span>ints<span class="re">)</span></span>
<span id="cb3-4"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>We define <code>outArray</code> to be a function (that is what the curly braces indicate) that takes two parameters <code>title</code> and <code>ints</code>. The last line of the function is its return value. The <code>$</code> verb, with a format string on its left and one or more values on its right is known as <code>format</code>. It returns a formatted string value in much the same way that <code>sprintf</code> might in a C-like language. This format string expects 3 arguments, a string, an integer and another string: namely, the title, a count of the number of integers in <code>ints</code> and a list of the integers in comma-separated format.</p>
<p>The monadic verb <code>#</code> applied to an array is known as <code>length</code> and gives the length of the array. So <code>#ints</code> is the number of integers in the array.</p>
<p>The monadic verb <code>csv</code> when applied to a generic array returns a string containing the array values in comma-separated format. The monadic verb <code>,</code>, known as <code>enlist</code>, converts our integer array into a generic array. The monadic verb <code>print</code> prints its argument to standard output. (The monadic verb <code>say</code>, seen later, does the same as <code>print</code> but appends a newline.)</p>
</section>
<section id="assignment-and-output" class="level3">
<h3 class="anchored" data-anchor-id="assignment-and-output">Assignment and Output</h3>
<p>We can define an array, <code>ints</code>, and display it with our function:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb4-1">ints<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">31</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span></span>
<span id="cb4-2">outArray<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">["</span>Initial<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">";</span> ints<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">]</span>    </span></code></pre></div></div>
<p>A variable name followed by a colon (:) is known as <code>assign</code>. The variable named on the left is assigned the value of the expression on the right. <code>OutArray</code> is just a variable that has been assigned the value of a lambda (function).</p>
</section>
<section id="sort-the-array" class="level3">
<h3 class="anchored" data-anchor-id="sort-the-array">Sort the Array</h3>
<p>We can sort the integer array and assign the sorted array to the variable <code>sortedInts</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb5-1">sortedInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> ints<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[&lt;</span>ints<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">]</span></span>
<span id="cb5-2">outArray<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">["</span>Sorted<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">";</span> sortedInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">]</span></span></code></pre></div></div>
<p>The monadic verb <code>&lt;</code>, known as <code>ascend</code>, when applied to an array of integers, <code>ints</code> say, gives an array of the same length in which the value of each element of the new array is an index into the original array.<br>
Picking elements from <code>ints</code> using that array of indexes will result in an array of the elements in the original array arranged in ascending order. (Indexes in Goal start at zero)</p>
<p>So for example:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb6-1">ints<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">31</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span></span>
<span id="cb6-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">&lt;</span>ints</span></code></pre></div></div>
<p>gives</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb7-1"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span></span></code></pre></div></div>
<p>If we pick the 5th, 4th, 1st, 3rd, 2nd, 6th and 0th elements from <code>ints</code> we get:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb8-1"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">31</span> </span></code></pre></div></div>
<p>So <code>&lt;ints</code> is an array of 7 indexes into <code>ints</code>. We can pick the values at each of these indexes by ‘indexing’ our <code>ints</code> array with the list of indexes:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb9-1">ints<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[&lt;</span>int<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">]</span></span></code></pre></div></div>
<p>is equivalent to:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb10-1">ints<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">]</span></span></code></pre></div></div>
<p>and results in:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb11-1"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">31</span> </span></code></pre></div></div>
</section>
<section id="select-the-odd-integers" class="level3">
<h3 class="anchored" data-anchor-id="select-the-odd-integers">Select the Odd Integers</h3>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb12-1">oddInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> sortedInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[&amp;</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">!</span>sortedInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">]</span></span>
<span id="cb12-2">outArray<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">["</span>Odd<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">";</span> oddInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">]</span></span></code></pre></div></div>
<p>Remainder modulus 2 is obtained with the dyadic <code>!</code> verb such that <code>2!sortedInts</code> results in an array of 0s and 1s of the same length as <code>sortedInts</code> but with a 0 in the place of every integer that is even and a 1 in the place of every odd integer. So, given <code>sortedInts</code> (2 3 5 6 7 8 31)</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb13-1"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">!</span>sortedInts</span></code></pre></div></div>
<p>gives:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb14-1"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span></span></code></pre></div></div>
<p>In which each position that contains a 1 corresponds to an odd number in <code>sortedInts</code>. The monadic verb <code>&amp;</code>, known as <code>where</code>, when given an array of 0s and 1s returns an array of those indexes that contain a 1. So:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb15" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb15-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">&amp;</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">!</span>sortedInts</span></code></pre></div></div>
<p>gives:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb16" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb16-1"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span></span></code></pre></div></div>
<p>Indexing <code>sortedInts</code> by this array gives us an array of those elements that are odd.</p>
</section>
<section id="reading-from-the-environment" class="level3">
<h3 class="anchored" data-anchor-id="reading-from-the-environment">Reading from the Environment</h3>
<p>Access to the arguments with which the Goal script was invoked is obtained through the global variable <code>ARGS</code>. If Goal is invoked as</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb17" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb17-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">goal</span> intlist.goal 2 3 4 5</span></code></pre></div></div>
<p>then <code>ARGS</code> contains an array of the following string values: <code>"intlist.goal" "2" "3" "4" "5"</code>. We would like to discard the first element which contains the script name and convert the remaining elements to an integer array. The dyadic verb <code>_</code> when presented with an array as its right argument, y say, and an integer as its left argument, x say, is known as <code>drop</code> and will return a new array made from all but the first x elements of y.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb18" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb18-1">argvInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"</span>i<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"$</span>'1_ARGS</span>
<span id="cb18-2">outArray<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">["</span>ArgvInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">";</span> argvInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">]</span></span></code></pre></div></div>
<p>So</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb19" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb19-1">1_ARGS</span></code></pre></div></div>
<p>drops the first element of <code>ARGS</code> and returns the result as a new array. But this is an array of strings and we want an array of integers.</p>
<p>The dyadic adverb <code>'</code>, with a verb on its left and an array on its right is known as <code>each</code>. <code>Each</code> is similar to the map function in many other functional languages - it will apply the verb to each of the elements of the array resulting in a new array.</p>
<p>The monadic verb “i”$ when given a string as its argument is known as <code>parse</code> and, more specifically, the dyadic verb <code>$</code> with its hardwired left argument of “i” will parse a string into an integer. So the combination of <code>"i"$</code> and <code>each</code> will convert each string element into an integer element. Given the above value for <code>ARGS</code></p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb20" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb20-1">argvInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"</span>i<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"$</span>'1_ARGS</span></code></pre></div></div>
<p>will set <code>argvInts</code> to the integer array with value:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb21" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb21-1"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span></span></code></pre></div></div>
<p>This assignment could be slightly simplified because <code>"i"$</code> will operate on an array argument and so, rather than employing the use of <code>each</code>, we could have written the line as:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb22" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb22-1">argvInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"</span>i<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"$</span>1_ARGS</span></code></pre></div></div>
<p>But is serves to illustrate the use of <code>each</code> and so has been left in.</p>
</section>
<section id="reading-from-a-file" class="level3">
<h3 class="anchored" data-anchor-id="reading-from-a-file">Reading from a File</h3>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb23" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb23-1">fileInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">*"</span>i<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"$</span>csv 'read <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"./</span>fileints<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">.</span>csv<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"</span></span>
<span id="cb23-2">outArray<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">["</span>FileInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">";</span> fileInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">]</span></span></code></pre></div></div>
<p>We read the contents of the file “./fileints.csv” with:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb24" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb24-1">read <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"./</span>fileints<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">.</span>csv<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"</span></span></code></pre></div></div>
<p>which returns the string:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb25" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb25-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">55</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">25</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">15</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"</span></span></code></pre></div></div>
<p>We can convert that to an array of strings by using the monadic form of the verb <code>csv</code> which will parse a string into comma-separated components:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb26" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb26-1">csv read <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"./</span>fileints<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">.</span>csv<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"</span></span></code></pre></div></div>
<p>gives:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb27" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb27-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,"</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">55</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">25</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">15</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"</span></span></code></pre></div></div>
<p>This is potentially a multi-row array containing a row for each line of CSV content in the file. In our case we know that we only have a single line but we still have a 1x4 array of strings. We can convert this to a 1x4 array of integers with:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb28" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb28-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"</span>i<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"$</span>csv read <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"./</span>fileints<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">.</span>csv<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"</span></span></code></pre></div></div>
<p>And, finally, we can select the first row using the monadic <code>first</code> verb. So our final assignment looks like this:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb29" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb29-1">fileInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">*"</span>i<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"$</span>csv 'read <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"./</span>fileints<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">.</span>csv<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"</span></span></code></pre></div></div>
<p>The apostrophe (’) character that was prepended onto the <code>read</code> verb is known as <code>try</code>. <code>Try</code> will cause an early return, with a suitable error message, if <code>read</code> returns an error. For example:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb30" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb30-1"> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"open ./fileints.csv: no such file or directory"</span></span></code></pre></div></div>
<p>Without <code>try</code> control would continue into <code>csv</code> and beyond and the actual error message would be lost.</p>
</section>
<section id="combine-without-duplicates" class="level3">
<h3 class="anchored" data-anchor-id="combine-without-duplicates">Combine without Duplicates</h3>
<p>To combine three integer arrays into a single array and remove duplicates we make use of the dyadic <code>join</code> verb (,) and the monadic <code>distinct</code> verb (?).</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb31" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb31-1">combinedInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">?</span>oddInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> argvInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> fileInts</span>
<span id="cb31-2">outArray<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">["</span>CombinedInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">";</span> combinedInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">]</span></span></code></pre></div></div>
<p>First the arrays are joined into a single array and then the duplicates are removed by applying the <code>distinct</code> verb.</p>
</section>
<section id="calculate-the-average" class="level3">
<h3 class="anchored" data-anchor-id="calculate-the-average">Calculate the Average</h3>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb32" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb32-1">average<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">{</span><span class="re">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">+/x</span><span class="re">)</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">%#x}</span> combinedInts</span>
<span id="cb32-2">say <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"</span>average<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">%</span>f<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"$</span>average</span></code></pre></div></div>
<p>We construct a function to calculate the average value of an array of integers. Unless we declare the names of a function’s arguments they are assumed to be named x, y and z. If you want a function with more than 3 arguments you need to define the names of the arguments as we did for the outArray function above. Our average function looks like this (with spaces added for readability):</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb33" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb33-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">{</span><span class="re">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">+/x</span><span class="re">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">%</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">#x}</span></span></code></pre></div></div>
<p>The expression <code>(+/x)</code> calculates the sum of the integers in x. The expression <code>#x</code> calculates the length of x - the number of elements in x. The verb <code>%</code> performs floating point division. We have to bracket the components that calculate the sum because Goal is right-associative and without the bracketing the function would be parsed as <code>(+/)(x % #x)</code> which is not what we want.</p>
<p>The adverb ‘/’ is known as <code>fold</code>. With a verb on its left it applies the verb between each of the elements of the array on its right. So with the dyadic verb (+), known as <code>add</code>, the expression +/x sums the integers in the array x.</p>
<p>Our function is invoked with <code>combinedInts</code> as its x argument by what is known as “Implicit At Indexing” - When Goal sees two nouns together (in this case a function and an integer array) it assumes that we want to call the function with the array as its argument. Equivalent ways of invoking the function would be by using square brackets (M-expression), using ‘@’ (known as <code>Apply At</code>) or using ‘.’ (known as <code>Apply</code>). So all of the following are equivalent:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb34" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb34-1">average<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="re">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">+/</span>combinedInts<span class="re">)</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">%#</span>combinedInts</span>
<span id="cb34-2">average<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">{</span><span class="re">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">+/x</span><span class="re">)</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">%#x}</span> combinedInts</span>
<span id="cb34-3">average<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">{</span><span class="re">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">+/x</span><span class="re">)</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">%#x}[</span>combinedInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">]</span></span>
<span id="cb34-4">average<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">{</span><span class="re">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">+/x</span><span class="re">)</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">%#x}@</span>combinedInts</span>
<span id="cb34-5">average<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">{</span><span class="re">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">+/x</span><span class="re">)</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">%#x}.,</span>combinedInts</span></code></pre></div></div>
</section>
<section id="split-into-higher-and-lower-arrays" class="level3">
<h3 class="anchored" data-anchor-id="split-into-higher-and-lower-arrays">Split into Higher and Lower Arrays</h3>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb35" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb35-1">higher<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">{x@&amp;x</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">&gt;</span> average<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">}[</span>combinedInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">]</span></span>
<span id="cb35-2">outArray<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">["</span>Higher<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">";</span>higher<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">]</span></span>
<span id="cb35-3"></span>
<span id="cb35-4">lower<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">{x@&amp;~x</span> in higher<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">}[</span>combinedInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">]</span></span>
<span id="cb35-5">outArray<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">["</span>Lower<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">";</span>lower<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">]</span></span></code></pre></div></div>
<p>Given our variable <code>average</code> that contains our calculated average and our <code>combinedInts</code> array:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb36" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb36-1">say <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"</span>average<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">%</span>f<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"$</span>average</span>
<span id="cb36-2">outArray<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">["</span>CombinedInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">";</span> combinedInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">]</span></span></code></pre></div></div>
<p>gives:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb37" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb37-1">average<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">16.333333</span></span>
<span id="cb37-2">CombinedInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9</span>]<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">31</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">55</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">25</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">15</span></span></code></pre></div></div>
<p>The expression</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb38" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb38-1">combinedInts <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">&gt;</span> average</span></code></pre></div></div>
<p>results in an integer array in which each element of <code>combinedInts</code> which is greater than the <code>average</code> scalar value is replaced with a 1 and all other elements are replaced with a zero.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb39" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb39-1"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span></span></code></pre></div></div>
<p>We can find the indices of these ones using (‘&amp;’) <code>where</code>:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb40" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb40-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">&amp;</span>combinedInts <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">&gt;</span> average</span></code></pre></div></div>
<p>These are the indices into <code>combinedInts</code> at which elements that are greater than <code>average</code> can be found:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb41" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb41-1"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span></span></code></pre></div></div>
<p>Indexing <code>combinedInts</code> using these indexes:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb42" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb42-1">combinedInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">@&amp;</span>combinedInts <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">&gt;</span> average</span></code></pre></div></div>
<p>gives:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb43" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb43-1"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">31</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">55</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">25</span></span></code></pre></div></div>
<p>Tidying it up and placing into a function:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb44" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb44-1">higher<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">{x@&amp;x</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">&gt;</span> average<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">}</span>combinedInts</span>
<span id="cb44-2">outArray<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">["</span>Higher<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">";</span>higher<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">]</span></span></code></pre></div></div>
<p>gives:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb45" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb45-1">Higher<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>]<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">31</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">55</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">25</span></span></code></pre></div></div>
<p>To find those elements that are not higher than <code>average</code> we calculate:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb46" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb46-1">combinedInts in higher</span></code></pre></div></div>
<p>which returns:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb47" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb47-1"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span></span></code></pre></div></div>
<p>which is an integer array containing a 1 for each element in <code>combinedInts</code> that is also in <code>higher</code>. But we want those elements that are not in <code>higher</code>.</p>
<p>We can apply <code>not</code> to this array:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb48" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb48-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">~</span>combinedInts in higher</span></code></pre></div></div>
<p>giving:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb49" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb49-1"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span></span></code></pre></div></div>
<p>We can express these 1s as indexes using <code>where</code>:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb50" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb50-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">&amp;~</span>combinedInts in higher</span></code></pre></div></div>
<p>which gives:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb51" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb51-1"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span></span></code></pre></div></div>
<p>Using these to index into <code>combinedInts</code>:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb52" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb52-1">combinedInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">@&amp;~</span>combinedInts in higher</span></code></pre></div></div>
<p>gives us those integers in <code>combinedInts</code> that are not in <code>higher</code>:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb53" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb53-1"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">15</span></span></code></pre></div></div>
<p>Wrapping it all up into a function and applying the function to <code>combinedInts</code>:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb54" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb54-1">lower<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">{x@&amp;~x</span> in higher<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">}[</span>combinedInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">]</span></span>
<span id="cb54-2">outArray<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">["</span>Lower<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">";</span>lower<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">]</span></span></code></pre></div></div>
<p>gives:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb55" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb55-1">Lower<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>]<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">15</span></span></code></pre></div></div>
</section>
<section id="in-summary" class="level3">
<h3 class="anchored" data-anchor-id="in-summary">In Summary</h3>
<p>Much to my surprise, I found working with Goal to be more satisfying that working with both Ivy and J.</p>
<p>The reach of Ivy is (quite deliberately) somewhat limited and as a result I found that, when using Ivy, I was unable to perform some of the parts of this task.</p>
<p>At the other end of the spectrum, J is a more complex language to learn, having a more difficult syntax involving digraphs and the concept of rank which needs to be understood in order to handle higher dimensional arrays.</p>
<p>Goal feels as though it sits comfortably in between the two, is slightly more easy on the eye than J, and has much more functionality than Ivy. Goal would be my go-to APL-like language of choice.</p>


</section>

 ]]></description>
  <category>APL</category>
  <category>Goal</category>
  <guid>https://www.oldgang.net/notebooks/posts/goal/goal.html</guid>
  <pubDate>Wed, 20 Dec 2023 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Ivy: An APL-Like Calculator</title>
  <dc:creator>John Bates</dc:creator>
  <link>https://www.oldgang.net/notebooks/posts/ivy/ivy.html</link>
  <description><![CDATA[ 




<p>Six months ago I wrote about my <a href="../../../notebooks/posts/the_lure_of_j/the_lure_of_j.html">experience with J</a>, another APL-like language. I had invested a lot of time learning a new language, and one that was very different to anything that I had used before. Ivy is a much simpler language than J, and I was keen to see whether my experience with J made it easier to pick up and also to see just how capable this small language was.</p>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Note
</div>
</div>
<div class="callout-body-container callout-body">
<p>The source code for Ivy is available on GitHub (<a href="https://github.com/robpike/ivy">here</a>) and documentation can be found <a href="https://pkg.go.dev/robpike.io/ivy">here</a>.</p>
<p>If you do start to experiment with Ivy I recommend <a href="https://github.com/fzipp/ivy-prompt">Ivy-Prompt</a> - a line editor wrapper for Ivy with tab-completion and input history.</p>
</div>
</div>
<p>Ivy was written by Rob Pike and, I think, named after Ken Iverson who developed APL in the 1950s and 1960s. Unlike APL which uses a special character set, or J in which the operators of the language consist of combinations of punctuation characters, the input to Ivy is ASCII and the operators have short alphabetic names.</p>
<p>Ivy also has exact rational arithmetic supporting integers with up to 10000 digits and for irrational numbers, or integers with more than 10000 digits, high-precision floating point using 256 bits of mantissa. In fact, Ivy supports arbitrary precision arithmetic and these default values really just control how many digits of a result Ivy is prepared to print to the display before resorting to the more compact floating point format.</p>
<p>If you are used to working with calculators it comes as a bit of a shock that a sum like:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb1-1"><span class="re">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">/</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span><span class="re">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">/</span> <span class="re">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">/</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9</span><span class="re">)</span></span></code></pre></div></div>
<p>results in the value <code>27/40</code>.</p>
<p>If you want a floating point result you need to force the overall result to have a floating point representation:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb2-1">float <span class="re">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">/</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span><span class="re">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">/</span> <span class="re">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">/</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">9</span><span class="re">)</span></span></code></pre></div></div>
<p>which gives <code>0.675</code>.</p>
<p>In addition to user-defined operators, Ivy has 53 unary and type-converting operators, 53 binary operators, and 6 higher level operators (adverbs in J terminology) that can be applied to existing operators to modify their behaviour.</p>
<p>In common with J, operators all have the same precedence, and expressions are evaluated in right-associative order. So, unary operators apply to everything to their right, and binary operators apply to the operand immediately to their left and to everything to their right.</p>
<p>I was keen to see how Ivy would cope with my simple list manipulation task that I had performed in my <a href="../../../notebooks/posts/the_lure_of_j/the_lure_of_j.html">lure of J</a> notebook. That task involved the following steps - their implementation in Ivy is given below:</p>
<ol type="1">
<li><p>Write a function, <code>outArray</code> that, given a string title and a vector of integers as its two parameters, outputs that vector as a comma-separated list, preceded by the title, a count of the number of integers in square-brackets and a colon. So, called with the parameters <code>"Initial"</code> and <code>1 2 3 4</code>, it would return:</p>
<p><code>Initial [4]: 1, 2, 3, 4</code></p></li>
<li><p>Assign a small vector of ints, say, the vector: <code>31 5 7 6 3 2 8</code> to the variable <code>ints</code>.</p></li>
<li><p>Use the <code>outArray</code> function to output the <code>ints</code> vector with the title “Initial”.</p></li>
<li><p>Create a new vector, <code>sortedInts</code>, from the original <code>ints</code> which contains the elements but sorted into ascending order, and output it with the outArray function using the title “Sorted”.</p></li>
<li><p>Create a list, <code>oddInts</code>, that contains just those ints from <code>sortedInts</code> that are odd and output it with the title “Odd”.</p></li>
<li><p>Create a list, <code>argvInts</code>, that has been read from the command line and output it with the title “argvInts”.</p></li>
<li><p>Create a list, <code>fileInts</code>, that has been read from a file on the filesystem that contains a single line of comma-separated integers and output it with the title “FileInts”.</p></li>
<li><p>Combine the <code>oddInts</code>, <code>argvInts</code>, and <code>fileInts</code> arrays into a single list, <code>combinedInts</code>, without duplicates and output it with the title “CombinedInts”.</p></li>
<li><p>Calculate the average of the numbers in the <code>combinedInts</code> array and store it in the scalar <code>average</code>.</p></li>
<li><p>Split the numbers in the <code>combinedInts</code> array into two distinct arrays, <code>higher</code> and <code>lower</code> such that <code>higher</code> contains those ints that are higher than the value in <code>average</code> and <code>lower</code> contains the remaining ints. Output both <code>higher</code> and <code>lower</code> with `outArray’.</p></li>
</ol>
<section id="the-outarray-function" class="level3">
<h3 class="anchored" data-anchor-id="the-outarray-function">The OutArray Function</h3>
<p>I chose not to attempt a pure J to Ivy conversion for two reasons. Firstly, I wanted to explore what tools were available in the Ivy language and, secondly, I feared that my rather naive attempts at writing J functions would be exposed and I’d feel the need to re-write the J notebook.</p>
<p>A user-defined function to combine two integers with a comma and a space is useful as a helper function.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb3-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">#</span> Join a and b with a comma and space<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">.</span></span>
<span id="cb3-2">op a comma b <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=</span> <span class="re">(</span>text a<span class="re">)</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">', '</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span><span class="re">(</span>text b<span class="re">)</span></span></code></pre></div></div>
<p>In Ivy this declares a user-defined operator with the name <code>comma</code> that takes two arguments: <code>a</code> as its left-hand argument and <code>b</code> as its right-hand argument. The expression to right of the equals sign defines the body of the operator - in this case a simple expression.</p>
<p>The binary comma operator will combine its arguments into a single vector.</p>
<p>Elements of a vector are normally printed with a separating space between each element. However, if all of the elements in a vector are characters then, as a special case, they are printed without spaces between them.</p>
<p>To ensure that all of the elements in the vector returned by the comma operator are characters we apply the <code>text</code> operator to the ints <code>a</code> and <code>b</code>.</p>
<p>The same trick is performed in the body of the <code>outArray</code> operator to prevent Ivy from inserting unwanted spaces.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb4-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">#</span> Output title<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> count of ints and comma<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">-</span>separated ints<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">.</span></span>
<span id="cb4-2">op title outArray ints <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=</span></span>
<span id="cb4-3">    title<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"[",</span> <span class="re">(</span>text rho ints<span class="re">)</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"</span>]<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">",</span> comma<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">/</span> ints</span></code></pre></div></div>
<p>The arguments to <code>outArray</code> are <code>title</code> on the left-hand side and <code>ints</code> on the right-hand size. Within the body of the operator definition these are treated as local variables.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb5-1">rho ints</span></code></pre></div></div>
<p>will give us the length of the <code>ints</code> vector. Applying <code>text</code> to the result will ensure that the overall value is a string.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb6-1">text rho ints</span></code></pre></div></div>
<p>The final part of the line <code>comma/ ints</code> is using the Ivy Reduce operator (/). Reduce modifies the operator that precedes it so that it applies the operator between each of its arguments. The easiest way to see this is by application to the plus operator. In Ivy <code>+/ 1 2 3 4</code> is the same as <code>1+2+3+4</code>. Similarly ’*/ 1 2 3 4’ is the same as <code>1*2*3*4</code>.</p>
<p>Care needs to be taken to remember that an Ivy expression is parsed from right to left. So <code>-/ 1 2 3 4</code> is equivalent to <code>1-2-3-4</code> which is parsed as 1-(2-(3-4)) and so has the value -2 rather than -8 which would be the value in a language where the expression was parsed from left to right.</p>
</section>
<section id="assignment-and-output" class="level3">
<h3 class="anchored" data-anchor-id="assignment-and-output">Assignment and Output</h3>
<p>We can assign a vector of integers to the variable <code>ints</code> like this:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb7-1">ints <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">31</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span></span></code></pre></div></div>
<p>And we can use our <code>outArray</code> operator to display their value:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb8-1"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Initial'</span> outArray ints</span>
<span id="cb8-2">Initial<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>]<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">31</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span></span></code></pre></div></div>
</section>
<section id="sort-the-list" class="level3">
<h3 class="anchored" data-anchor-id="sort-the-list">Sort the List</h3>
<p>A vector can be sorted using Ivy’s <code>up</code> (or <code>down</code>) operators. <code>Up</code> is a unary operator which when applied to a vector B, say, returns a vector of the same length as B that contains that ordering of indices which, if used to access the elements of B, would return them in ascending order.</p>
<p>We can apply <code>up</code> to our <code>ints</code> vector:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb9-1">up ints</span>
<span id="cb9-2"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span></span></code></pre></div></div>
<p>So, to return the elements of <code>ints</code> in ascending order we would need to take the 6th element of <code>ints</code> followed by the 5th, followed by the 2nd and so on.</p>
<p>Indexing of a vector is performed using the [] notation. Index numbering begins at 1 in Ivy. So the first element of vector B is <code>B[1]</code>.</p>
<p>A vector can also be indexed using another vector and this results in a new vector. For example, if <code>B</code> is indexed by the vector <code>3 1 2</code> we would obtain a new vector whose elements were made from the third, first and second elements of B, in that order.</p>
<p>So, indexing the <code>ints</code> vector by the result of applying <code>up</code> will give us the sorted values from <code>ints</code>:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb10-1">sortedInts <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=</span> ints<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[</span>up ints<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">]</span></span>
<span id="cb10-2"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Sorted'</span> outArray sortedInts</span>
<span id="cb10-3">Sorted<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>]<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">31</span></span></code></pre></div></div>
</section>
<section id="select-the-odd-integers" class="level3">
<h3 class="anchored" data-anchor-id="select-the-odd-integers">Select the Odd Integers</h3>
<p>We can select the odd integers from our vector, and assign them to the variable <code>oddInts</code>, with this:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb11-1">oddInts <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=</span> <span class="re">(</span>sortedInts mod <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="re">)</span> sel sortedInts</span></code></pre></div></div>
<p>This makes use of two binary operators: <code>mod</code> and <code>sel</code>. The use of round brackets reminds us that Ivy evaluates a line of input from right to left and so we need the brackets to obtain the desired result. Without the brackets ivy would parse the line as:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb12-1">oddInts <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=</span> sortedInts mod <span class="re">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> sel sortedInts<span class="re">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">#</span> wrong</span></code></pre></div></div>
<p>The operator <code>mod</code> when used in <code>A mod B</code> returns the remainder on dividing A by B. Any integer divided by 2 will have a remainder of 0 if it is even and a remainder of 1 if it is odd.</p>
<p>Ivy, being an array processing language, operates on entire vectors and so it makes sense to pass a vector as the left-hand operator of <code>mod</code> the resulting vector being the element-wise application of <code>mod 2</code>. You can think of the right-hand argument <code>2</code> as being widened to be a vector of the same length as the left-hand argument but consisting of all <code>2</code>s.</p>
<p>So, for each element of the vector <code>sortedInts</code> that is odd we will see a <code>1</code> in the corresponding position in the result and for each element of <code>sortedInts</code> that is even we will see a <code>0</code> in the corresponding position.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb13-1">sortedInts</span>
<span id="cb13-2"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">31</span></span>
<span id="cb13-3">sortedInts mod <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span></span>
<span id="cb13-4"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span></span></code></pre></div></div>
<p>The <code>sel</code> operator allows us to create a new vector by selecting 0 or more items from each position in a vector. In its simplest form it is used like this:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb14-1">A sel B</span></code></pre></div></div>
<p>Where A is a vector of the same length as B and contains either the value 0 or the value 1 in each position. Then for each position in A that contains a 1 the value from the corresponding position in B is used in the resulting vector and for each position in A that contains a 0 the value from the corresponding position in B is ignored.</p>
<p>So, if <code>sortedInts</code> contains 7 elements, the expression <code>1 1 1 0 0 0 0 sel sortedInts</code> would return a vector of length 3 containing the first three elements of <code>sortedInts</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb15" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb15-1">sortedInts</span>
<span id="cb15-2"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">31</span></span>
<span id="cb15-3"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> sel sortedInts</span>
<span id="cb15-4"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span></span></code></pre></div></div>
<p>As we saw above, our application of <code>mod 2</code> resulted in a vector of the same length as <code>sortedInts</code> containing just 0s and 1s and with 1s in the positions that corresponded to odd numbers. So, combining the two and printing the results gives us our vector of odd integers.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb16" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb16-1">oddInts <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=</span> <span class="re">(</span>sortedInts mod <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="re">)</span> sel sortedInts</span>
<span id="cb16-2"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Odd'</span> outArray oddInts</span>
<span id="cb16-3">Odd<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>]<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">31</span></span></code></pre></div></div>
</section>
<section id="reading-from-the-environment-and-from-a-file" class="level3">
<h3 class="anchored" data-anchor-id="reading-from-the-environment-and-from-a-file">Reading from the Environment and from a File</h3>
<p>Ivy does not have the rich library environment that other APL-like languages have. Nor does it have an <code>each</code> operator that might make it easier to produce an operator that could read CSV formatted strings. So (currently) it would not be possible to reproduce steps six and seven of our task to read CSV input from the environment or filesystem. However, it does have a mechanism in which Ivy statements can be read from a file on disk and so we will read <code>argvInts</code> and <code>fileInts</code> using that method.</p>
<p>To read statements from a disk and continue execution we use the <code>)get</code> command, passing it the name of the file containing the ivy statements that we want to read.</p>
<p>So, if the file <code>argvAndFileInts.ivy</code> contains the following two lines:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb17" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb17-1">argvInts <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">33</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">44</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">55</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">66</span></span>
<span id="cb17-2">fileInts <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span></span></code></pre></div></div>
<p>We can read these values in from disk and print them out.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb18" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb18-1"><span class="re">)</span>get <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"</span>argvAndFileInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">.</span>ivy<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">"</span></span>
<span id="cb18-2"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'ArgvInts'</span> outArray argvInts</span>
<span id="cb18-3">ArgvInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>]<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">33</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">44</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">55</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">66</span></span>
<span id="cb18-4"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'FileInts'</span> outArray fileInts</span>
<span id="cb18-5">FileInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>]<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span></span></code></pre></div></div>
</section>
<section id="combine-without-duplicates" class="level3">
<h3 class="anchored" data-anchor-id="combine-without-duplicates">Combine without Duplicates</h3>
<p>We now need to combine the three vectors <code>oddInts</code>, <code>argvInts</code> and <code>fileInts</code> into a single vector of integers without retaining duplicates. This is made easy for us in Ivy with the <code>unique</code> operator.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb19" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb19-1">combinedInts <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=</span> unique oddInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> argvInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> fileInts</span></code></pre></div></div>
<p>The <code>unique</code> operator is a unary operator that, when applied to an argument B, will return a new vector that is made by removing all of the duplicate elements from B.</p>
<p>There is a second operator in use in the above assignment - the binary comma operator (,). The comma operator, when applied between vectors A and B, will create a new vector in which the elements of B are appended to the elements of A creating a new vector whose length is the sum of the lengths of A and B.</p>
<p>The right-associative nature of ivy means that first <code>argvInts</code> and <code>fileInts</code> are combined and then the result of that combination is combined with <code>oddInts</code> leaving a single vector that consists of all of the elements of the three vectors (including any duplicate elements).</p>
<p>The application of <code>unique</code> to this combined vector gives us our value for <code>combinedInts</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb20" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb20-1">combinedInts <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=</span> unique oddInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> argvInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> fileInts</span>
<span id="cb20-2"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'CombinedInts'</span> outArray combinedInts</span>
<span id="cb20-3">CombinedInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">11</span>]<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">31</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">33</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">44</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">55</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">66</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span></span></code></pre></div></div>
<p>Our three input vectors were each of length 4 but our resulting vector is of length 11. Both <code>fileInts</code> and <code>oddInts</code> contained an element 5 and this has been collapsed into a single element by the application of <code>unique</code>.</p>
</section>
<section id="calculate-the-average" class="level3">
<h3 class="anchored" data-anchor-id="calculate-the-average">Calculate the Average</h3>
<p>We need to calculate the average of our combined vector. To do this we need to sum the elements of <code>combinedInts</code> and divide the sum by the number of elements it contains.</p>
<p>Counting the number of elements in a vector is easy, we can do this with the unary operator <code>count</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb21" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb21-1">count combinedInts</span>
<span id="cb21-2"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">11</span></span></code></pre></div></div>
<p>Ivy has no traditional looping statements but it contains a number of operators that operate along the axes of a vector. In this simple example we have been working with vectors of a single dimension but Ivy can handle multiple dimensions.</p>
<p>The operator <code>/</code> (known as Reduce) would be called an adverb in J because it modifies the operation of a verb. In Ivy, Reduce modifies the behaviour of an operator. In the construction of our <code>outArray</code> operator we used Reduce to modify the behaviour of our <code>comma</code> operator. Here we are going to use Reduce to modify the operation of the ‘+’ operator. The expression</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb22" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb22-1">combinedInts </span>
<span id="cb22-2"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">31</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">33</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">44</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">55</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">66</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span></span>
<span id="cb22-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">+/</span> combinedInts </span>
<span id="cb22-4"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">274</span></span></code></pre></div></div>
<p>is equivalent to laying out the elements of <code>combinedInts</code> with the ‘+’ operator between them and so it calculates the sum of the elements. We can use this to calculate the average of the elements. Our first attempt might be:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb23" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb23-1">average <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=</span> <span class="re">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">+/</span> combinedInts<span class="re">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">/</span> count combinedInts</span>
<span id="cb23-2"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Average: '</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span>  text average</span>
<span id="cb23-3">Average<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">274</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">/</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">11</span></span></code></pre></div></div>
<p>This reminds us that Ivy uses exact rational arithmetic and so in order to see our average as a floating point number (for comparison with our <a href="../../../notebooks/posts/the_lure_of_j/the_lure_of_j.html">J calculation</a>) we need to convert part of it to float. We can do this with the unary operator <code>float</code>:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb24" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb24-1">average <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=</span> <span class="re">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">+/</span> combinedInts<span class="re">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">/</span> float count combinedInts</span>
<span id="cb24-2"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Average: '</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span>  text average</span>
<span id="cb24-3">Average<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">24.9090909091</span></span></code></pre></div></div>
</section>
<section id="split-into-higher-and-lower-vectors" class="level3">
<h3 class="anchored" data-anchor-id="split-into-higher-and-lower-vectors">Split into Higher and Lower Vectors</h3>
<p>The last part of the program is to split the <code>combinedInts</code> vector into two distinct vectors with one vector containing all the integers that are higher than the average and the other containing the remaining integers.</p>
<p>The binary operator ‘&gt;’, when applied to a vector A and an element B will result in a vector of the same length as A but with a one in each position where the element of A was greater than B and a 0 elsewhere. So evaluating <code>combinedInts &gt; average</code> results in this:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb25" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb25-1">combinedInts </span>
<span id="cb25-2"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">31</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">33</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">44</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">55</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">66</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span></span>
<span id="cb25-3">combinedInts <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">&gt;</span> average</span>
<span id="cb25-4"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span></span></code></pre></div></div>
<p>We can use this with the <code>sel</code> operator (see above) to extract just those elements that are higher than average using bracketing to force the desired interpretation:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb26" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb26-1">higher <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=</span> <span class="re">(</span>combinedInts <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">&gt;</span> average<span class="re">)</span> sel combinedInts</span>
<span id="cb26-2"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Higher: '</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> text higher</span>
<span id="cb26-3">Higher<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">31</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">33</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">44</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">55</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">66</span></span></code></pre></div></div>
<p>To calculate the rest we make use of two new operators: <code>in</code> and <code>not</code>.</p>
<p>When applied to vectors A and B, <code>A in B</code> will result in a vector of the same length as A but with a 1 in each position where the element in the corresponding position in A was also in the vector B and a 0 in each position where the element in the corresponding position in A was not found in B.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb27" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb27-1">combinedInts </span>
<span id="cb27-2"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">31</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">33</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">44</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">55</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">66</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span></span>
<span id="cb27-3">higher</span>
<span id="cb27-4"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">31</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">33</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">44</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">55</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">66</span></span>
<span id="cb27-5">combinedInts in higher</span>
<span id="cb27-6"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span></span></code></pre></div></div>
<p>This tells us which elements are in higher, but we want to know which elements are not in higher. We can reverse the result using the <code>not</code> operator. The <code>not</code> operator will replace all of the 0s in a vector with 1s and all of the 1s in a vector with 0s:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb28" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb28-1">not combinedInts in higher</span>
<span id="cb28-2"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span></span></code></pre></div></div>
<p>Combining this with the <code>sel</code> operator:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb29" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb29-1">lower <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=</span> <span class="re">(</span>not combinedInts in higher<span class="re">)</span> sel combinedInts</span>
<span id="cb29-2"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Lower: '</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> text lower</span>
<span id="cb29-3">Lower<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span></span></code></pre></div></div>
</section>
<section id="in-summary" class="level3">
<h3 class="anchored" data-anchor-id="in-summary">In Summary</h3>
<p>There were many things that made working with Ivy a really pleasurable experience, and only one or two things that didn’t.</p>
<ul>
<li>Ivy’s use of relatively short operator names means that expressions, although not as terse as those of J, are still concise and this keeps the code window small and readable.</li>
<li>The source code for Ivy, written in Go, is very readable and so it is possible to get an understanding of what is happening behind the scenes. This was not the case with the J source code - at least, I didn’t think so.</li>
<li>Rob Pike describes Ivy as <em>a plaything and a work in progress</em>. A few people have cloned Ivy and added their own extensions but I really hope that Rob is going to extend the language a little further.</li>
<li>I found that there were some calculations that I did not feel I could perform in Ivy. This is quite likely as a result of my inexperience with APL-like languages. But, for example, the lack of an ‘each’ iterator stumped me on a few occasions.</li>
<li>Ivy is described, on its GitHub page as a calculator and it is a very capable calculator. It think it is fair to say that is a gross understatement - Ivy is much more than that.</li>
</ul>


</section>

 ]]></description>
  <category>APL</category>
  <category>Ivy</category>
  <guid>https://www.oldgang.net/notebooks/posts/ivy/ivy.html</guid>
  <pubDate>Wed, 22 Nov 2023 00:00:00 GMT</pubDate>
</item>
<item>
  <title>TimeSheet: A Time Keeper in Go</title>
  <dc:creator>John Bates</dc:creator>
  <link>https://www.oldgang.net/notebooks/posts/go_timesheet/go_timesheet.html</link>
  <description><![CDATA[ 




<p>This notebook discusses a timesheet program written in the Go programming language. The timesheet program was originally written in F#, later re-written in C# and then more recently, re-written again in Go. Part of the motivation for re-writing in Go was to obtain a single executable that could be run to generate a monthly timesheet.</p>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Note
</div>
</div>
<div class="callout-body-container callout-body">
<p>The source code that accompanies this notebook is available on GitHub (<a href="https://github.com/Vextasy/TimeSheet_Go">here</a>) and is licensed for personal or commercial use under the terms of the MIT license. The C# version is also available on GitHub (<a href="https://github.com/Vextasy/TimeSheet_Csharp">here</a>) but takes slightly different parameters and is documented <a href="../../../notebooks/posts/csharp_timesheet/csharp_timesheet.html">here</a>.</p>
</div>
</div>
<p>Much of the material from the orginal C# notebook is repeated here, but the command line usage and any Go specific notes are peculiar to this notebook.</p>
<p>The Microsoft Outlook calendar has a very simple interface for the creation of events. With little more than a click and a re-size it is possible to drag out a rectangle that corresponds to a period of time in the working day and populate it with a description of the activity that either did occupy, or is planned to occupy, that slice of time.</p>
<p>To have a Microsoft Outlook calendar requires a Microsoft 365 subscription but there is no requirement to use the Microsoft Outlook app to manage the calendar if an alternative is available. As a macOS user, I find that by adding my Microsoft account details to my macOS “Internet Accounts” I am able to manage events in my Outlook calendar from my Mac and my iPhone. This turns out to be useful if I am away from my work environment but, to be honest, I have got used to the Outlook interface and I prefer that.</p>
<section id="summary-of-operation" class="level1">
<h1>Summary of Operation</h1>
<p>The timesheet software (hereafter referred to as TimeSheet) allows me to report on my activity over time and have the individual activities summarised by project and sub-project in a format that makes it easy for me to see how much work I have done on individual projects, sub-projects within projects, or tasks within sub-projects.</p>
<p>The interpretation of project, sub-project and task is very loose. The important part of the interpretation is that they are considered to be hierarchical such that a task is wholly contained within a sub-project and a sub-project is wholly contained within a project. Sometimes a project might be used to represent a customer and the sub-project might represent a distinct piece of work for that customer.</p>
<p>All is made clear by an example. Consider the following entries made in Outlook between 10:00 and 13:00 on the 1st and 2nd of November.</p>
<div class="quarto-figure quarto-figure-left">
<figure class="figure">
<p><img src="https://www.oldgang.net/notebooks/posts/go_timesheet/outlook_input.png" class="img-fluid figure-img"></p>
<figcaption>Figure 1 - The entries in Outlook</figcaption>
</figure>
</div>
<p>TimeSheet examines Outlook for calendar entries that occur between a range of dates. These entries are known as events in Outlook.</p>
<p>Only entries whose text matches a given format are considered:</p>
<p><em>&lt;project&gt; – &lt;sub-project&gt; – &lt;task details&gt;</em></p>
<p>Project, sub-project and task detail are separated by a single dash character which may be surrounded by whitespace characters. Project and sub-project may only contain letters, digits, an underscore character or a forward slash character. Task details may contain any characters.</p>
<p>Entries with any other format are ignored. So, from the entries above, the only Outlook task that is ignored is the “Early Lunch” task as it does not match the desired format. All of the other tasks in our range of days are considered to be tasks of interest and are collected.</p>
<p>The duration of the task is taken from the duration of the corresponding Outlook event.</p>
<p>TimeSheet is a command line application that runs on macOS and Windows. It writes its output to standard output. Given the data shown in Figure 1 above, Figure 2 shows the output produced by running TimeSheet on that data.</p>
<div class="quarto-figure quarto-figure-left">
<figure class="figure">
<p><img src="https://www.oldgang.net/notebooks/posts/go_timesheet/timesheet_output.png" class="img-fluid figure-img"></p>
<figcaption>Figure 2 - The output from TimeSheet</figcaption>
</figure>
</div>
<p>The first line shows the range of dates for which events in Outlook have been read. In this example, TimeSheet has been asked to look at all dates between 1st November and 30th November (inclusive) but, to keep things simple, I have only made entries in Outlook for the days of 1st and 2nd of November.</p>
<p>After that comes a block of output for each distinct project found within those events.</p>
<p>Each block begins with a line containing the name of the project and the total time spent working on that project.</p>
<p>Then, for each week included in the range of days for which TimeSheet has been run, we see a breakdown of the time spent each day on the project (in hours and minutes). The weekly breakdown is arranged to begin on a Monday. In this example our data for the 1st and 2nd of November would appear in cells 3 and 4 of the row for the week beginning 30th October. We can see that we worked for 2 hours on Project X on the first of November and that this was the only week (so far) in the month that we have worked on ProjectX.</p>
<p>Next, for the project, we see a block of lines showing the total time that we have spent on each sub-project within the project. We see that, for ProjectX, we have spent 1 hour 30 minutes on documentation and 30 minutes on testing. This sub-project summary is only for sub-projects within the main project. Were there to also be a Doc sub-project within, say, the CompanyY project then its Doc sub-project would be totalled separately. So it is OK to have sub-projects with the same title within different projects and we will never double count them.</p>
<p>After the sub-projects block comes the task block. The task block is more than just a list of tasks; it is a summary of the distinct tasks within the sub-projects. So if multiple entries exist with the same project, sub-project and task detail they appear as just one line here and their total duration is summarised. Working on a task, taking a break, and then working on the same task at some point later on will result in just a single line in this task block with the duration being the total time that has been spent on that task in the (project and sub-project and) date range. Each line in the task block begins with the sub-project to which the task belongs. This allows us to distinguish between tasks that have the same task detail within different sub-projects of a project.</p>
<p>In summary, we use a very simple input format within an event in Outlook and we generate a textual output that enables us to see at a glance a summary of what we have been doing at the project, sub-project, task and day level.</p>
</section>
<section id="complications" class="level1">
<h1>Complications</h1>
<p>There are two complications that didn’t exist in the original COM-based F# timesheet program:</p>
<ol type="1">
<li>Outlook is now part of Microsoft 365 and so the Outlook event data lives within Microsoft’s servers rather than on the local machine.</li>
<li>To be able to obtain access to the data on Microsoft’s servers some kind of authentication will need to be done.</li>
</ol>
<p>Outlook event data can be read using the Microsoft Graph API. But, because we want to run TimeSheet on our local machine, we will need to be able to authenticate first and so I will look at the authentication mechanism first in this document. Authentication is the trickiest part of this interaction with Microsoft’s servers but its complexity is handled by the Microsoft Graph SDK for Go and the Kiota Azure Identity authentication provider library for Go.</p>
<p>Once authentication has been configured we can obtain a client for calling the Microsoft Graph service. The graph service client allows us to query calendar events between a range of dates and once we can do that we then have our event data available to play with.</p>
</section>
<section id="authentication-with-microsoft-entra-id" class="level1">
<h1>Authentication with Microsoft Entra ID</h1>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Note
</div>
</div>
<div class="callout-body-container callout-body">
<p>Microsoft Entra ID was formerly known as Microsoft Azure Active Directory.</p>
</div>
</div>
<section id="configuration" class="level2">
<h2 class="anchored" data-anchor-id="configuration">Configuration</h2>
<p>The following configuration steps are required to arrange that our TimeSheet application can gain access to Outlook events through the Microsoft Graph service.</p>
<ol type="1">
<li>We will create an App Registration within Microsoft Entra ID. This will act as the representative of our application.</li>
<li>We will agree a shared secret that will be known to both the app registration and our application. When we run the application we can use this to prove to the app registration that we are who we claim to be.</li>
<li>We will grant the app registration permission to access the Microsoft Graph service.</li>
</ol>
<section id="creating-the-app-registration" class="level3">
<h3 class="anchored" data-anchor-id="creating-the-app-registration">Creating the App Registration</h3>
<p>Microsoft’s documentation for the creation of an App Registration can be found here: <a href="https://learn.microsoft.com/en-gb/entra/identity-platform/quickstart-register-app">Register an application with the Microsoft identity platform</a></p>
<p>We’ll give our app registration the name of “TimeSheet” and when asked “Who can use this application” we will select the option “Accounts in this organisational directory only”. We will not be allowing access to our Outlook calendar to anyone other than us.</p>
<p>Click the “Register” button to create the app registration. The overview page of the app registration will now show a value for the Application ID (also known as the Client ID). This value will be used by our timesheet application to indicate to Microsoft Entra the app registration to which it is associated.</p>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Note
</div>
</div>
<div class="callout-body-container callout-body">
<p>In the Microsoft terminology our timesheet application is known as a “Confidential client application” in the sense that it is one that we can trust to safely keep an application secret - such as a shared password. This is in contrast to, say, an application that ran in a web browser which would be considered to be a “Public client application”</p>
</div>
</div>
</section>
<section id="assigning-a-shared-secret" class="level3">
<h3 class="anchored" data-anchor-id="assigning-a-shared-secret">Assigning a Shared Secret</h3>
<p>We can now create a shared password that will allow our timesheet application to prove to the app registration that it is who it claims to be. We do this from within the “Certificates &amp; secrets” section of the app registration. Select the “Client secrets” tab and click on “New client secret”. Enter a description such as “Timesheet shared secret” and choose an expiry period of 24 months (which is the longest that Microsoft Entra will allow us to set).</p>
<p>At this point it is very important to make a copy of the shared secret “Value”. This will be the only opportunity to capture it and so make a point of storing it safely. <em>To be clear, the sequence of characters that appears in the “Value” field is the one that we need to copy and not the “Secret ID” which is of no importance to us.</em></p>
<p>We now have a Client ID and a shared secret. These two things are sufficient to enable our password application to prove to the appropriate app registration that it is who it claims to be.</p>
</section>
<section id="granting-permissions" class="level3">
<h3 class="anchored" data-anchor-id="granting-permissions">Granting Permissions</h3>
<p>We now need to give the app registration permission to use the Microsoft Graph service. Still within the Microsoft Entra app registration we click on the API Permissions blade. You should see that, by default, the app registration already has the Microsoft.Graph User.Read permission. This will allow the app registration to read the current users profile. We will add a couple of additional permissions.</p>
<p>Click on “Add a permission” and choose Microsoft APIs -&gt; Microsoft Graph -&gt; Application Permissions.</p>
<p>Click to put a tick against: Calendars.Read and User.Read.All. These allow us to “Read calendars in all mailboxes” and “Read all users’ full profiles”.</p>
<p>Click the “Add permissions” button.</p>
<p>The Calendars.Read and the User.Read.All permissions require admin consent before they can be used. As long as we have the required administrative permission we can obtain these permissions by clicking on the “Grant admin consent for …” button. If this button is disabled it is because the logged in user does not have permission to do this.</p>
<p>Click the “Grant admin consent for …” button (where the elipsis is replaced by the name of your Microsoft Entra tenant).</p>
<p>We should now have sufficient permission for our application, once suitably configured, to read Outlook calendar events.</p>
</section>
</section>
</section>
<section id="the-timesheet-application" class="level1">
<h1>The TimeSheet Application</h1>
<p>The TimeSheet application is written in Go. There are four services with a very simple relationship between them. The main module reads the command line flags and the locally stored secrets and, through the timesheet service, wires up the other three services. It then uses them to generate the textual result and writes it to standard output.</p>
<div class="cell" data-layout-align="default">
<div class="cell-output-display">
<div>
<p></p><figure class="figure"><p></p>
<div>
<pre class="mermaid mermaid-js">flowchart LR
  m(main) --&gt; t(timesheet)
  t(timesheet) --&gt; g(graph)
  t(timesheet) --&gt; c(calendar)
  t(timesheet) --&gt; d(dump)
</pre>
</div>
<p></p></figure><p></p>
</div>
</div>
</div>
<p>The parameters and secrets read by the main module include the range of dates of interest, the Outlook username, and the authentication details. The authentication details are passed to the graph service which uses them to obtain a client that can access the Microsoft Graph service. The timesheet service calls the graph service with username and range of dates to obtain a list of the relevant events that happened for the given user between the two dates. The timesheet service passes this list of tasks to the calendar service which summarises and aggregates event times, returning them as a list of Projects. These are then passed to the dump service to convert them into our desired output format for output on standard output.</p>
<p>There are four steps required to get to the point where we can retrieve Outlook event data:</p>
<ol type="1">
<li>Register this app with the Microsoft Identity Platform: We have already done this (see above).</li>
<li>Create an AuthenticationProvider object.</li>
<li>Get a Graph Service Client and Adapter object.</li>
</ol>
<section id="authenticating-to-the-graph-service" class="level2">
<h2 class="anchored" data-anchor-id="authenticating-to-the-graph-service">Authenticating to the Graph Service</h2>
<p>Before we can make use of the Microsoft Graph service we need to prove to it that we are who we claim to be. And to do that we need to show it the shared secret that we agreed when we configured the Microsoft Entra app registration.</p>
<p>Microsoft have made this process relatively easy by providing the <a href="https://github.com/microsoftgraph/msgraph-sdk-go">Microsoft Graph SDK for Go</a> and the <a href="https://github.com/microsoft/kiota-authentication-azure-go">Kiota Azure Identity authentication provider library for Go</a>.</p>
<p>We can install the Graph SDK and the Kiota Azure Identity authentication provider library for Go with:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb1-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">go</span> get github.com/microsoftgraph/msgraph-sdk-go</span>
<span id="cb1-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">go</span> get github.com/microsoft/kiota-authentication-azure-go</span></code></pre></div></div>
</section>
<section id="create-credentials-and-graph-service-client" class="level2">
<h2 class="anchored" data-anchor-id="create-credentials-and-graph-service-client">Create Credentials and Graph Service Client</h2>
<p>There are three pieces of information that we will need to supply to the Authentication Provider:</p>
<ul>
<li><strong>The Azure Tenant ID</strong>: This can be found from the app registration overview page as the Directory (tenant) ID.</li>
<li><strong>The App Registration Client ID</strong>: Found on the app registration overview page.</li>
<li><strong>The Client Secret</strong>: The shared secret that we created on the app registration “Clients &amp; Certificates” blade and which you saved to a safe place.</li>
</ul>
<p>With these we can obtain credentials that we can provide to the graph service client constructor.</p>
<p>The code to do that looks like this:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode go code-with-copy"><code class="sourceCode go"><span id="cb2-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">import</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb2-2">    azidentity <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"github.com/Azure/azure-sdk-for-go/sdk/azidentity"</span></span>
<span id="cb2-3">    msgraphsdk <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"github.com/microsoftgraph/msgraph-sdk-go"</span></span>
<span id="cb2-4"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb2-5"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb2-6"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">type</span> Auth <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-7">    TenantId     <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">string</span></span>
<span id="cb2-8">    ClientId     <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">string</span></span>
<span id="cb2-9">    ClientSecret <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">string</span></span>
<span id="cb2-10"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-11"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb2-12"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">func</span> NewGraphSvc<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>auth domain<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Auth<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> domain<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>GraphSvc <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-13">    cred<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> azidentity<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>NewClientSecretCredential<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb2-14">        auth<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>TenantId<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-15">        auth<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>ClientId<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-16">        auth<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>ClientSecret<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-17">        <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-18">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb2-19">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-20">        fmt<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Printf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Error creating credentials: %v</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb2-21">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> graphSvc<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>auth<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> auth<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> client<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-22">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-23">    scopes <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">string</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"https://graph.microsoft.com/.default"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-24">    client<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> msgraphsdk<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>NewGraphServiceClientWithCredentials<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>cred<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> scopes<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb2-25">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-26">        fmt<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Printf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Error creating graph client: %v</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb2-27">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> graphSvc<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>auth<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> auth<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> client<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-28">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-29">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> graphSvc<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-30">        auth<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span>   auth<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-31">        client<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> client<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-32">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-33"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>The <code>Auth</code> structure will have been populated with values in the main module. To do that TimeSheet expects to find an “.envrc” file in the current directory that looks something like this:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode sh code-with-copy"><code class="sourceCode bash"><span id="cb3-1"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">export</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">UserName</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"john.bates@oldgang.net"</span>,</span>
<span id="cb3-2"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">export</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">TenantId</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"g3xxxxxx-9999-xxxx-xxxx-1xxxx1x2xxxx"</span>,</span>
<span id="cb3-3"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">export</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">ClientId</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"xpxxxxf1-9999-4xxe-xxxx-dxxxx3x4x9x5"</span>,</span>
<span id="cb3-4"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">export</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">ClientSecret</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"kljkliexxxxxxxllxxxxxlxxxxxxCP(sGbYFwcWP"</span></span></code></pre></div></div>
<p>There are other ways of authenticating with the Microsoft Graph service but this shared secret method works well enough in this case.</p>
<p>We now have a Graph Service client that can be used to query the Graph Service for Outlook events.</p>
</section>
<section id="querying-the-graph-service" class="level2">
<h2 class="anchored" data-anchor-id="querying-the-graph-service">Querying the Graph Service</h2>
<p>The graph service implements the <code>GraphSvc</code> interface:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode go code-with-copy"><code class="sourceCode go"><span id="cb4-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">type</span> GraphSvc <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">interface</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb4-2">    Read<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>userName <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">string</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> fromDate time<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Time<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> toDate time<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Time<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">([]</span>Task<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">error</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb4-3"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>Calling <code>Read</code> with a username and a date range and returns a slice of Tasks. These are all of the Outlook events for the given user that both match the required pattern in their description (see above) and started between the given dates (inclusive).</p>
<p>We start by finding the list of all users and then look for the one whose UserPrincipalName is the same as our userName. We call this our targetUser and we will need the targetUser ID later to filter the calendar events.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode go code-with-copy"><code class="sourceCode go"><span id="cb5-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">func</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>svc graphSvc<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> Read<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>userName <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">string</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> fromDate time<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Time<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> toDate time<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Time<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">([]</span>domain<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Task<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">error</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb5-2"></span>
<span id="cb5-3">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> svc<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>client <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb5-4">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span>domain<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Task<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{},</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span></span>
<span id="cb5-5">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb5-6">    allusers<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> svc<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>client<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Users<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">().</span>Get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>context<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Background<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb5-7">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb5-8">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span>domain<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Task<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{},</span> err</span>
<span id="cb5-9">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb5-10">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> allusers <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">||</span> allusers<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>GetValue<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb5-11">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span>domain<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Task<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{},</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span></span>
<span id="cb5-12">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb5-13">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">var</span> targetUser models<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Userable</span>
<span id="cb5-14">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> _<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> user <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">range</span> allusers<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>GetValue<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb5-15">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>user<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>GetUserPrincipalName<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> userName <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb5-16">            targetUser <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> user</span>
<span id="cb5-17">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb5-18">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb5-19">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> targetUser <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb5-20">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span>domain<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Task<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{},</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span></span>
<span id="cb5-21">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb5-22">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span></code></pre></div></div>
<p>Microsoft Outlook stores its dates as UTC dates, so we need to convert our ‘from’ and ‘to’ dates from localtime to UTC before we can use them to filter events in Outlook. We are only interested in fetching the event subject and its start and end dates.</p>
<p>By default, a request will only return a small number of results. To request the maximum number of results we need to provide a value for the ‘Top’ query parameter and in the Go Graph SDK this has to be provided as a pointer to an integer.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode go code-with-copy"><code class="sourceCode go"><span id="cb6-1">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Got the user. Now get the tasks for that user.</span></span>
<span id="cb6-2">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Microsoft graph stores datetimes in UTC. So convert our range to UTC before filtering.</span></span>
<span id="cb6-3">    start <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> fromDate<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>UTC<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">().</span>Format<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"2006-01-02T15:04:05.0000000"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb6-4">    end <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> toDate<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>UTC<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">().</span>Format<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"2006-01-02T15:04:05.0000000"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb6-5">    filter <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> fmt<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Sprintf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"start/DateTime ge '%s' and start/DateTime le '%s' and IsAllDay eq false"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> start<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb6-6">    query <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> users<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>ItemCalendarEventsRequestBuilderGetQueryParameters<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-7">        Select<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">string</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"subject"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"start"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"end"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb6-8">        Filter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>filter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb6-9">        Top<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span>    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;[]</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">int32</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">999</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">],</span></span>
<span id="cb6-10">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb6-11">    options <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> users<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>ItemCalendarEventsRequestBuilderGetRequestConfiguration<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-12">        QueryParameters<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>query<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb6-13">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb6-14">    events<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> svc<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>client<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Users<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">().</span>ByUserId<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(*</span>targetUser<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>GetId<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()).</span>Calendar<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">().</span>Events<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">().</span>Get<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>context<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Background<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(),</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>options<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb6-15">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-16">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span>domain<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Task<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{},</span> err</span>
<span id="cb6-17">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb6-18">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> events <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">||</span> events<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>GetValue<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-19">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span>domain<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Task<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{},</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span></span>
<span id="cb6-20">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb6-21">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span></code></pre></div></div>
<p>Once we have the events, we reject those that do not match our desired pattern, convert the event dates back into local time, and calculate the duration of each before returning them as a slice of Tasks.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode go code-with-copy"><code class="sourceCode go"><span id="cb7-1">    tasks <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span>domain<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Task<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb7-2">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> _<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> ev <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">range</span> events<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>GetValue<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb7-3">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> ev <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">||</span> ev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>GetSubject<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb7-4">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">continue</span></span>
<span id="cb7-5">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb7-6"></span>
<span id="cb7-7">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// proj (- group) - description</span></span>
<span id="cb7-8">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">var</span> pat <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">`^\s*([\w/]+)(?:\s*-\s*([\w/]+))?\s*-\s*(.*)`</span></span>
<span id="cb7-9"></span>
<span id="cb7-10">        matches <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> regexp<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>MustCompile<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>pat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">).</span>FindStringSubmatch<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(*</span>ev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>GetSubject<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">())</span></span>
<span id="cb7-11">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> matches <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">||</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">len</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>matches<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Entire expression plus each subexpression.</span></span>
<span id="cb7-12">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">continue</span></span>
<span id="cb7-13">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb7-14">        proj <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> matches<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb7-15">        group <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> matches<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb7-16">        desc <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> matches<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb7-17">        _start <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> ev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>GetStart<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span></span>
<span id="cb7-18">        _end <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> ev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>GetEnd<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span></span>
<span id="cb7-19">        start<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> time<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Parse<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"2006-01-02T15:04:05.0000000"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>_start<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>GetDateTime<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">())</span></span>
<span id="cb7-20">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb7-21">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span>domain<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Task<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{},</span> fmt<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Errorf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"failed to parse start time: %v"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb7-22">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb7-23">        end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> time<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Parse<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"2006-01-02T15:04:05.0000000"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>_end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>GetDateTime<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">())</span></span>
<span id="cb7-24">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb7-25">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span>domain<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Task<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{},</span> fmt<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Errorf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"failed to parse end time: %v"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb7-26">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb7-27">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Convert back from UTC to local time.</span></span>
<span id="cb7-28">        start <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> start<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Local<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span></span>
<span id="cb7-29">        end <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Local<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span></span>
<span id="cb7-30">        duration <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Sub<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>start<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb7-31">        tasks <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">append</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>tasks<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> domain<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Task<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb7-32">            Project<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span>  proj<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb7-33">            Group<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span>    group<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb7-34">            Desc<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span>     desc<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb7-35">            Start<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span>    start<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb7-36">            Duration<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> duration<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb7-37">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">})</span></span>
<span id="cb7-38">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb7-39">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> tasks<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span></span>
<span id="cb7-40"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>It is all downhill from here, the main module calls the <code>CalendarSvc</code> interface on the calendar service to summarise the Tasks into a slice of Projects.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode go code-with-copy"><code class="sourceCode go"><span id="cb8-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">type</span> CalendarSvc <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">interface</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb8-2">    Aggregate<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>tasks <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span>Task<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]*</span>Project</span>
<span id="cb8-3"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>Then it calls the <code>DumpSvc</code> interface on the dump service to turn the slice of Projects into formatted text for output.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode go code-with-copy"><code class="sourceCode go"><span id="cb9-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">type</span> DumpSvc <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">interface</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb9-2">    Projects<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>projects <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]*</span>Project<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">string</span></span>
<span id="cb9-3"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
</section>
</section>
<section id="usage" class="level1">
<h1>Usage</h1>
<p>There are only three things that the TimeSheet application needs to know to produce some output: a starting date, an ending date and a user name.</p>
<p>The username, which is often the same for each invocation, is most usefully stored in the .envrc file. But an alternative username may be provided with the ‘-user’ flag.</p>
<p>If run without any arguments the TimeSheet application will assume a date range that spans the start to the end (inclusive) of the current month.</p>
<p>The ‘-n’ flag can be used to request a timesheet for ‘n’ months back from the current month and the date range that spans that month will be used. So, for example, running:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb10-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">./TimeSheet</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-n</span> 1</span></code></pre></div></div>
<p>will output a timesheet summary for the previous month.</p>
<p>The ‘-from’ and ‘-to’ flags may be used to provide alternative starting and ending dates. The dates must be provided in the YYYY-MM-DD format and may be used in conjunction with the ‘-n’ flag to modify the dates that the ’-n- flag would imply.</p>
<p>So, for example, the following would only report on events in my calendar that happened on the first day of November 2023.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb11-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">./TimeSheet</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-from</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'2023-11-01'</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-to</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'2023-11-01'</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-user</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'john.bates@oldgang.net'</span></span></code></pre></div></div>
<p>Because a time sheet can only be constructed after the event, and is most usefully constructed as soon after the event as possible, the most common invocation is:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb12-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">./TimeSheet</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-n</span> 1</span></code></pre></div></div>
<p>to summarise last month’s timesheet.</p>


</section>

 ]]></description>
  <category>Timesheet</category>
  <category>Go</category>
  <category>Microsoft Graph</category>
  <category>Microsoft Outlook</category>
  <category>Microsoft Entra ID</category>
  <guid>https://www.oldgang.net/notebooks/posts/go_timesheet/go_timesheet.html</guid>
  <pubDate>Sat, 18 Nov 2023 00:00:00 GMT</pubDate>
</item>
<item>
  <title>TimeSheet: A Time Keeper in C#</title>
  <dc:creator>John Bates</dc:creator>
  <link>https://www.oldgang.net/notebooks/posts/csharp_timesheet/csharp_timesheet.html</link>
  <description><![CDATA[ 




<p>The Microsoft Outlook calendar has a very simple interface for the creation of events. With little more than a click and a re-size it is possible to drag out a rectangle that corresponds to a period of time in the working day and populate it with a description of the activity that either did occupy, or is planned to occupy, that slice of time.</p>
<p>Many years ago I took advantage of this to keep a record of my activity against a number of projects. Back then the programmer’s interface to Microsoft Outlook was very much tied to the Windows operating system through its COM binary interface and later through its .NET COM-interop-assemblies. My original timesheet program was written in F# and, because it used such an interface, was limited to running on Windows. In this document I describe a re-write of the software in C# for the .NET Core platform, enabling it to run on macOS as well as Windows.</p>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Note
</div>
</div>
<div class="callout-body-container callout-body">
<p>The source code that accompanies this notebook is available on GitHub (<a href="https://github.com/Vextasy/TimeSheet_CSharp">here</a>) and is licensed for personal or commercial use under the terms of the MIT license.</p>
<p>A Go version of the timesheet program is also available on GitHub (<a href="https://github.com/Vextasy/TimeSheet_Go">here</a>) but takes slightly different parameters and is documented <a href="../../../notebooks/posts/go_timesheet/go_timesheet.html">here</a>.</p>
</div>
</div>
<section id="summary-of-operation" class="level1">
<h1>Summary of Operation</h1>
<p>The timesheet software (hereafter referred to as TimeSheet) allows me to report on my activity over time and have the individual activities summarised by project and sub-project in a format that makes it easy for me to see how much work I have done on individual projects, sub-projects within projects, or tasks within sub-projects.</p>
<p>The interpretation of project, sub-project and task is very loose. The important part of the interpretation is that they are considered to be hierarchical such that a task is wholly contained within a sub-project and a sub-project is wholly contained within a project. Sometimes a project might be used to represent a customer and the sub-project might represent a distinct piece of work for that customer.</p>
<p>All is made clear by an example. Consider the following entries made in Outlook between 10:00 and 13:00 on the 1st and 2nd of November.</p>
<div class="quarto-figure quarto-figure-left">
<figure class="figure">
<p><img src="https://www.oldgang.net/notebooks/posts/csharp_timesheet/outlook_input.png" class="img-fluid figure-img"></p>
<figcaption>Figure 1 - The entries in Outlook</figcaption>
</figure>
</div>
<p>TimeSheet examines Outlook for calendar entries that occur between a range of dates. These entries are known as events in Outlook.</p>
<p>Only entries whose text matches a given format are considered:</p>
<p><em>&lt;project&gt; – &lt;sub-project&gt; – &lt;task details&gt;</em></p>
<p>Project, sub-project and task detail are separated by a single dash character which may be surrounded by whitespace characters. Project and sub-project may only contain letters, digits, an underscore character or a forward slash character. Task details may contain any characters.</p>
<p>Entries with any other format are ignored. So, from the entries above, the only Outlook task that is ignored is the “Early Lunch” task as it does not match the desired format. All of the other tasks in our range of days are considered to be tasks of interest and are collected.</p>
<p>The duration of the task is taken from the duration of the corresponding Outlook event.</p>
<p>TimeSheet is a command line application that runs on macOS and Windows. It writes its output to standard output. Given the data shown in Figure 1 above, Figure 2 shows the output produced by running TimeSheet on that data.</p>
<div class="quarto-figure quarto-figure-left">
<figure class="figure">
<p><img src="https://www.oldgang.net/notebooks/posts/csharp_timesheet/timesheet_output.png" class="img-fluid figure-img"></p>
<figcaption>Figure 2 - The output from TimeSheet</figcaption>
</figure>
</div>
<p>The first line shows the range of dates for which events in Outlook have been read. In this example, TimeSheet has been asked to look at all dates between 1st November and 30th November (inclusive) but, to keep things simple, I have only made entries in Outlook for the days of 1st and 2nd of November.</p>
<p>After that comes a block of output for each distinct project found within those events.</p>
<p>Each block begins with a line containing the name of the project and the total time spent working on that project.</p>
<p>Then, for each week included in the range of days for which TimeSheet has been run, we see a breakdown of the time spent each day on the project (in hours and minutes). The weekly breakdown is arranged to begin on a Monday. In this example our data for the 1st and 2nd of November would appear in cells 3 and 4 of the row for the week beginning 30th October. We can see that we worked for 2 hours on Project X on the first of November and that this was the only week (so far) in the month that we have worked on ProjectX.</p>
<p>Next, for the project, we see a block of lines showing the total time that we have spent on each sub-project within the project. We see that, for ProjectX, we have spent 1 hour 30 minutes on documentation and 30 minutes on testing. This sub-project summary is only for sub-projects within the main project. Were there to also be a Doc sub-project within, say, the CompanyY project then its Doc sub-project would be totalled separately. So it is OK to have sub-projects with the same title within different projects and we will never double count them.</p>
<p>After the sub-projects block comes the task block. The task block is more than just a list of tasks; it is a summary of the distinct tasks within the sub-projects. So if multiple entries exist with the same project, sub-project and task detail they appear as just one line here and their total duration is summarised. Working on a task, taking a break, and then working on the same task at some point later on will result in just a single line in this task block with the duration being the total time that has been spent on that task in the (project and sub-project and) date range. Each line in the task block begins with the sub-project to which the task belongs. This allows us to distinguish between tasks that have the same task detail within different sub-projects of a project.</p>
<p>In summary, we use a very simple input format within an event in Outlook and we generate a textual output that enables us to see at a glance a summary of what we have been doing at the project, sub-project, task and day level.</p>
</section>
<section id="complications" class="level1">
<h1>Complications</h1>
<p>There are two complications that didn’t exist in the original COM-based F# timesheet program:</p>
<ol type="1">
<li>Outlook is now part of Microsoft 365 and so the Outlook event data lives within Microsoft’s servers rather than on the local machine.</li>
<li>To be able to obtain access to the data on Microsoft’s servers some kind of authentication will need to be done.</li>
</ol>
<p>Outlook event data can be read using the Microsoft Graph API. But, because we want to run TimeSheet on our local machine, we will need to be able to authenticate first and so I will look at the authentication mechanism first in this document. Authentication is the trickiest part of this interaction with Microsoft’s servers but its complexity is handled by components of .NET which, thankfully, keeps the number of lines of user code required to be relatively low.</p>
<p>Once authentication has been configured we can obtain a client for calling the Microsoft Graph service. The graph service client allows us to query calendar events between a range of dates and once we can do that we then have our event data available to play with.</p>
</section>
<section id="authentication-with-microsoft-entra-id" class="level1">
<h1>Authentication with Microsoft Entra ID</h1>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Note
</div>
</div>
<div class="callout-body-container callout-body">
<p>Microsoft Entra ID was formerly known as Microsoft Azure Active Directory.</p>
</div>
</div>
<section id="configuration" class="level2">
<h2 class="anchored" data-anchor-id="configuration">Configuration</h2>
<p>The following configuration steps are required to arrange that our TimeSheet application can gain access to Outlook events through the Microsoft Graph service.</p>
<ol type="1">
<li>We will create an App Registration within Microsoft Entra ID. This will act as the representative of our application.</li>
<li>We will agree a shared secret that will be known to both the app registration and our application. When we run the application we can use this to prove to the app registration that we are who we claim to be.</li>
<li>We will grant the app registration permission to access the Microsoft Graph service.</li>
</ol>
<section id="creating-the-app-registration" class="level3">
<h3 class="anchored" data-anchor-id="creating-the-app-registration">Creating the App Registration</h3>
<p>Microsoft’s documentation for the creation of an App Registration can be found here: <a href="https://learn.microsoft.com/en-gb/entra/identity-platform/quickstart-register-app">Register an application with the Microsoft identity platform</a></p>
<p>We’ll give our app registration the name of “TimeSheet” and when asked “Who can use this application” we will select the option “Accounts in this organisational directory only”. We will not be allowing access to our Outlook calendar to anyone other than us.</p>
<p>Click the “Register” button to create the app registration. The overview page of the app registration will now show a value for the Application ID (also known as the Client ID). This value will be used by our timesheet application to indicate to Microsoft Entra the app registration to which it is associated.</p>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Note
</div>
</div>
<div class="callout-body-container callout-body">
<p>In the Microsoft terminology our timesheet application is known as a “Confidential client application” in the sense that it is one that we can trust to safely keep an application secret - such as a shared password. This is in contrast to, say, an application that ran in a web browser which would be considered to be a “Public client application”</p>
</div>
</div>
</section>
<section id="assigning-a-shared-secret" class="level3">
<h3 class="anchored" data-anchor-id="assigning-a-shared-secret">Assigning a Shared Secret</h3>
<p>We can now create a shared password that will allow our timesheet application to prove to the app registration that it is who it claims to be. We do this from within the “Certificates &amp; secrets” section of the app registration. Select the “Client secrets” tab and click on “New client secret”. Enter a description such as “Timesheet shared secret” and choose an expiry period of 24 months (which is the longest that Microsoft Entra will allow us to set).</p>
<p>At this point it is very important to make a copy of the shared secret “Value”. This will be the only opportunity to capture it and so make a point of storing it safely. <em>To be clear, the sequence of characters that appears in the “Value” field is the one that we need to copy and not the “Secret ID” which is of no importance to us.</em></p>
<p>We now have a Client ID and a shared secret. These two things are sufficient to enable our password application to prove to the appropriate app registration that it is who it claims to be.</p>
</section>
<section id="granting-permissions" class="level3">
<h3 class="anchored" data-anchor-id="granting-permissions">Granting Permissions</h3>
<p>We now need to give the app registration permission to use the Microsoft Graph service. Still within the Microsoft Entra app registration we click on the API Permissions blade. You should see that, by default, the app registration already has the Microsoft.Graph User.Read permission. This will allow the app registration to read the current users profile. We will add a couple of additional permissions.</p>
<p>Click on “Add a permission” and choose Microsoft APIs -&gt; Microsoft Graph -&gt; Application Permissions.</p>
<p>Click to put a tick against: Calendars.Read and User.Read.All. These allow us to “Read calendars in all mailboxes” and “Read all users’ full profiles”.</p>
<p>Click the “Add permissions” button.</p>
<p>The Calendars.Read and the User.Read.All permissions require admin consent before they can be used. As long as we have the required administrative permission we can obtain these permissions by clicking on the “Grant admin consent for …” button. If this button is disabled it is because the logged in user does not have permission to do this.</p>
<p>Click the “Grant admin consent for …” button (where the elipsis is replaced by the name of your Microsoft Entra tenant).</p>
<p>We should now have sufficient permission for our application, once suitably configured, to read Outlook calendar events.</p>
</section>
</section>
</section>
<section id="the-timesheet-application" class="level1">
<h1>The TimeSheet Application</h1>
<p>The TimeSheet application is written in C# for the Microsoft .NET Core platform. There are five modules with a very simple relationship between them. The main module wires up the other four modules and outputs the result to standard output.</p>
<div class="cell" data-layout-align="default">
<div class="cell-output-display">
<div>
<p></p><figure class="figure"><p></p>
<div>
<pre class="mermaid mermaid-js">flowchart LR
  p(param) --&gt; g(graph)
  g(graph) --&gt; c(calendar)
  c(calendar) --&gt; d(dumper)

  p --&gt; m(main)
  d --&gt; m(main)
</pre>
</div>
<p></p></figure><p></p>
</div>
</div>
</div>
<p>The param module gathers the parameters that will be used to query the calendar. These include the range of dates of interest and the authentication details. These are passed to the graph module which uses them to obtain a client that can access the Microsoft Graph service. The calendar module uses graph service client to query the service and return a set of calendar entries which it then groups and summarises by project. The dumper module is then responsible for formatting this summary and returning it to the main module.</p>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Note
</div>
</div>
<div class="callout-body-container callout-body">
<p>I talk of the calendar module in this document to refer to the task module in the code. The reason for this is to avoid confusing the task module with the .NET Task class. I also use the term module to refer to the C# namespace with the same name. This application was originally written in F# and will be later re-written in Go and I do not want to make changes to it purely to satisfy naming issues with the C# language and the .NET class library names.</p>
</div>
</div>
<p>Code for the main module looks like this:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode c# code-with-copy"><code class="sourceCode cs"><span id="cb1-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> Program</span>
<span id="cb1-2"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb1-3">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">static</span> async Task <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Main</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">string</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span> args<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb1-4">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb1-5">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Wire up the components.</span></span>
<span id="cb1-6">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">var</span> param <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> parameter<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Reader</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">New</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>args<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-7">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">var</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>graph<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> error<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> msgraph<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Client</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">New</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>param<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Auth</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-8">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>graph <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">null</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// error will be non-null</span></span>
<span id="cb1-9">            Console<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Error</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">WriteLine</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>error<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-10">            System<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Environment</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Exit</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-11">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-12">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">var</span> calendar <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> task<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Reader</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">New</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>graph<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-13">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">var</span> dumper <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> dump<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Dump</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">New</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>calendar<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-14"></span>
<span id="cb1-15">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Read the parameters</span></span>
<span id="cb1-16">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">var</span> userPrincipalName <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> param<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">UserPrincipalName</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-17">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">var</span> dateFrom <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> param<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">DateFrom</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-18">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">var</span> dateTo <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> param<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">DateTo</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb1-19">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>userPrincipalName <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">null</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb1-20">            Console<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Error</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">WriteLine</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"A value for UserPrincipalName is required"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-21">            System<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Environment</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Exit</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-22">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-23">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>dateFrom <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">null</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">||</span> dateTo <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">null</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb1-24">           Console<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Error</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">WriteLine</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"A value for both DateFrom and DateTo is required"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> </span>
<span id="cb1-25">            System<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Environment</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Exit</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-26">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-27"></span>
<span id="cb1-28">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Output the results</span></span>
<span id="cb1-29">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">var</span> output <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> await dumper<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summary</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>userPrincipalName<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> dateFrom<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Value</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> dateTo<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Value</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-30">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">foreach</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">var</span> s <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> output<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb1-31">            Console<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">WriteLine</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb1-32">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-33">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-34"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<section id="wiring-up" class="level2">
<h2 class="anchored" data-anchor-id="wiring-up">Wiring Up</h2>
<p>The param module contains the code to obtain not just the range of dates for which we are interested in calendar events, but also the name of the user whose calendar we will read and the details required to persuade the Microsoft Graph service to give us the data.</p>
<p>The graph module only needs to know about the authentication parameters. The calendar module is given a graph module to use and the dumper module is given a calendar module to use.</p>
<p>The dumper module satisfies the IDumper interface.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode c# code-with-copy"><code class="sourceCode cs"><span id="cb2-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">interface</span> IDumper <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-2">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span> Task<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>List<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">string</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summary</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">string</span> userPrincipalName<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> DateTime fromDate<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> DateTime toDate<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">bool</span> satweek<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">false</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb2-3"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>Interface IDumper is satisfied by just a simple <code>summary</code> function which, given a user name and a range of dates, returns the formatted output ready for printing to standard output.</p>
<p>The structure of this application is fairly simple to grasp but there are two bits that were new to me, and which were not required when the F# version of this application was written, and so I’ll describe them in this notebook: authenticating to the graph service and querying the graph service.</p>
</section>
<section id="authenticating-to-the-graph-service" class="level2">
<h2 class="anchored" data-anchor-id="authenticating-to-the-graph-service">Authenticating to the Graph Service</h2>
<p>Before we can make use of the Microsoft Graph service we need to prove to it that we are who we claim to be. And to do that we need to show it the shared secret that we agreed when we configured the Microsoft Entra app registration.</p>
<p>Microsoft have made this process much easier than it used to be by providing the Microsoft.Identity.Web.TokenAcquirerFactory class. The TokenAcquirerFactory class will manage the acquisition of Access (and other) tokens required for communication with Microsoft Graph.</p>
<p>There are four pieces of information that we need to provide:</p>
<ul>
<li><strong>The Azure Instance</strong>: In our case “https://login.microsoftonline.com”. This will be different if you are allowing access to a wider audience. But if restricting it to just members of our Microsoft Entra tenant then we need to use this value.</li>
<li><strong>The Azure Tenant ID</strong>: This can be found from the app registration overview page as the Directory (tenant) ID.</li>
<li><strong>The App Registration Client ID</strong>: Found on the app registration overview page.</li>
<li><strong>The Client Secret</strong>: The shared secret that we created on the app registration “Clients &amp; Certificates” blade and which you saved to a safe place.</li>
</ul>
<p>This information can be used with the TokenAcquirerFactory class to create a Microsoft Graph client with which we can query Microsoft Graph. The code to do that looks like this:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode c# code-with-copy"><code class="sourceCode cs"><span id="cb3-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">static</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>IClient<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">?</span> client<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">string</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">?</span> error<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">New</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>azure<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Auth</span> auth<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-2"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-3"></span>
<span id="cb3-4">    TokenAcquirerFactory tokenAcquirerFactory <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> TokenAcquirerFactory<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">GetDefaultInstance</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-5">    IServiceCollection services <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> tokenAcquirerFactory<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Services</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-6">    services</span>
<span id="cb3-7">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">AddMicrosoftGraph</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-8"></span>
<span id="cb3-9">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Ensure that the tokenAcquirerFactory has the required authentication configuration.</span></span>
<span id="cb3-10">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">var</span> C <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> tokenAcquirerFactory<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Configuration</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-11">    C<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"AzureAd:Instance"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> auth<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Instance</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-12">    C<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"AzureAd:TenantId"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> auth<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">TenantId</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-13">    C<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"AzureAd:ClientId"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> auth<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ClientId</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-14">    C<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"AzureAd:ClientCredentials:0:SourceType"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ClientSecret"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-15">    C<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"AzureAd:ClientCredentials:0:ClientSecret"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> auth<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ClientSecret</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb3-16"></span>
<span id="cb3-17">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">var</span> serviceProvider <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> tokenAcquirerFactory<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Build</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb3-18">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>serviceProvider <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">null</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-19">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">null</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Could not create service provider"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-20">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">var</span> graphclient <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> serviceProvider<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">GetService</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>GraphServiceClient<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;();</span></span>
<span id="cb3-21">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>graphclient <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">null</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-22">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">null</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Could not create graph service client"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-23">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Client</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>graphclient<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">null</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb3-24"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>This <code>New</code> function is passed an <code>azure.Auth</code> structure which contains the required authentication IDs and the shared client secret. It uses these to construct a Microsoft Graph client and uses the authentication information passed as its only argument to satisfy the authentication requirements.</p>
<p>The strange looking names of the entries in the TokenAcquirerFactory configuration are because normally it looks in an “Azure” section of the “appsettings.json” file to find this information. We do things slightly differently here to reduce the chances of accidently saving a configuration file to, for example, a Git repository. Instead, we keep our authentication parameters in an “env.private” file which we ensure is ignored by Git.</p>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Note
</div>
</div>
<div class="callout-body-container callout-body">
<p>On platforms other than Microsoft .NET we might use, say, a “.env” file which the operating system will hide from common view. But the TokenAcquirerFactory class will refuse to open a file with that name.</p>
</div>
</div>
<p>Our param module arranges to read the “env.private” file when it is constructed immediately after reading the “appsettings.json” file.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode c# code-with-copy"><code class="sourceCode cs"><span id="cb4-1"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">var</span> builder <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ConfigurationBuilder</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span></span>
<span id="cb4-2">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">SetBasePath</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>Directory<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">GetCurrentDirectory</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">())</span></span>
<span id="cb4-3">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">AddJsonFile</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"appsettings.json"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> optional<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">false</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> reloadOnChange<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">true</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb4-4">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">AddJsonFile</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"env.private"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> optional<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">false</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> reloadOnChange<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">false</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb4-5">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">AddEnvironmentVariables</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb4-6">IConfigurationRoot configuration <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> builder<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Build</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span></code></pre></div></div>
<p>We then use an “env.private” file that looks something like this (and we pass these value through in the <code>azure.Auth</code> structure when we create our graph module):</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode json code-with-copy"><code class="sourceCode json"><span id="cb5-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb5-2">    <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">//</span> <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">These</span> <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">are</span> <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">made</span> <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">up</span> <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">values.</span></span>
<span id="cb5-3">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"Instance"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"https://login.microsoftonline.com/"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb5-4">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"TenantId"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"f3xxxxxx-9999-xxxx-xxxx-1xxxx8x3xxxx"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb5-5">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"ClientId"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"xbxxxxf1-9999-4xxe-xxxx-dxxxx5x4x9x5"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb5-6">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"ClientSecret"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"kljkliexxxxxxxllxxxxxlxxxxxxCY7sG7nfwcWP"</span></span>
<span id="cb5-7"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>There are other ways of authenticating with the Microsoft Graph service but this shared secret method works well enough in this case.</p>
</section>
<section id="querying-the-graph-service" class="level2">
<h2 class="anchored" data-anchor-id="querying-the-graph-service">Querying the Graph Service</h2>
<p>The graph module implements a single interface on its Graph service client:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode c# code-with-copy"><code class="sourceCode cs"><span id="cb6-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">interface</span> IClient</span>
<span id="cb6-2"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-3">    Task<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>List<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>task<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Task</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">TimesheetItems</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">string</span> userPrincipalName<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> DateTime dateFrom<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> DateTime dateTo<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb6-4"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>The single function TimesheetItems takes a username and a date range and returns a list of task.Task objects.</p>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Note
</div>
</div>
<div class="callout-body-container callout-body">
<p>Unfortunately in this C# .NET version of the timesheet application there is a naming conflict between our task class and the .NET System.Threading.Tasks.Task class. To resolve this conflict we always refer to our task class as task.Task.</p>
</div>
</div>
<p>The TimesheetItems function looks like this:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode c# code-with-copy"><code class="sourceCode cs"><span id="cb7-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">public</span> async Task<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>List<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>task<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Task</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">TimesheetItems</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">string</span> userPrincipalName<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> DateTime dateFrom<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> DateTime dateTo<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb7-2">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">var</span> tasks <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> List<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>task<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Task</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;();</span></span>
<span id="cb7-3">        <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">var</span> users <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> await graphclient<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Users</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">GetAsync</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb7-4">            r <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=&gt;</span> r<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Options</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">WithAppOnly</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span></span>
<span id="cb7-5">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb7-6">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>users <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">null</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">||</span> users<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Value</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">null</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb7-7">            <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> tasks<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-8">        User<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">?</span> targetUser <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">null</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-9">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">foreach</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">var</span> user <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> users<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Value</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb7-10">            <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>user<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">UserPrincipalName</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> userPrincipalName<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb7-11">                targetUser <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> user<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-12">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb7-13">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>targetUser <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">null</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb7-14">            <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">var</span> events <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> await graphclient</span>
<span id="cb7-15">                <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Users</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span>$<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"{targetUser.Id}"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb7-16">                <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Calendar</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Events</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">GetAsync</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>r <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=&gt;</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb7-17">                    r<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">QueryParameters</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Select</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]{</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"subject"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"start"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"end"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb7-18">                    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Microsoft graph stores datetimes in UTC. So convert our range to UTC.</span></span>
<span id="cb7-19">                    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">var</span> start <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> dateFrom<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ToUniversalTime</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">().</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ToString</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"yyyy-MM-ddTHH:mm:ss.0000000"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb7-20">                    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">var</span> end <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> dateTo<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ToUniversalTime</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">().</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ToString</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"yyyy-MM-ddTHH:mm:ss.0000000"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span></span>
<span id="cb7-21">                    r<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">QueryParameters</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Filter</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> $<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"start/DateTime ge '{start}' and start/DateTime le '{end}' and IsAllDay eq false"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-22">                    r<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">QueryParameters</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Top</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">999</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-23">                    r<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Options</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">WithAppOnly</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb7-24">                <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">});</span></span>
<span id="cb7-25">            <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>events <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">null</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">||</span> events<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Value</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">null</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb7-26">                <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> tasks<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-27">            <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">var</span> eventList <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> events<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Value</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ToList</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb7-28">            <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">foreach</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">var</span> ev <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> eventList<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb7-29">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb7-30">                <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>ev <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">null</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">||</span> ev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Subject</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">null</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb7-31">                    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">continue</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-32">                <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// proj (- group) - description</span></span>
<span id="cb7-33">                <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">var</span> pat <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> @<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"^\s*([\w/]+)(?:\s*-\s*([\w/]+))?\s*-\s*(.*)"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-34">                <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">var</span> m <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> Regex<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Match</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>ev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Subject</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> pat<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-35">                <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>m<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Success</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">){</span></span>
<span id="cb7-36">                    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">string</span> proj <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> m<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Groups</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">].</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Value</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-37">                    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">string</span> group <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> m<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Groups</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">].</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Value</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-38">                    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">string</span> desc <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> m<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Groups</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">].</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Value</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-39">                    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// Convert back to local time.</span></span>
<span id="cb7-40">                    DateTime start <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> ev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Start</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ToDateTime</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">().</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ToLocalTime</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb7-41">                    DateTime end <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> ev<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">End</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ToDateTime</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">().</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ToLocalTime</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">();</span></span>
<span id="cb7-42">                    TimeSpan duration <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> end<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Subtract</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>start<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">);</span> </span>
<span id="cb7-43">                    tasks<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Add</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> task<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">Task</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>proj<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> group<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> desc<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> start<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> duration<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">));</span></span>
<span id="cb7-44">                <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb7-45">            <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb7-46">            <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> tasks<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-47">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb7-48">        <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> tasks<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb7-49">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>The TimesheetItems function has access to the Microsoft Graph service client that we created earlier in the local variable <code>graphclient</code>. The basic structure of the function, ignoring error checking, is this:</p>
<ul>
<li>Use the graph client to obtain a list of users.</li>
<li>Iterate through these users to identify our desired <code>targetUser</code></li>
<li>Use the graph client again to obtain a list of calendar events for the given <code>targetUser</code>.
<ul>
<li>Consider only events whose start time falls within the start and end bounds (inclusive) of our date range of interest having first converted our local time date range to UTC and ignoring all-day events.</li>
<li>Extract only the calendar event start time, end time and subject.</li>
<li>Use the <code>Top</code> parameter to request the maximum (999) number of events. The default is 10, so this is important.</li>
</ul></li>
<li>Having obtained a list of events further filter it to keep only those that match our <em>project - sub-project - task details</em> format. For this we use a regular expression.</li>
<li>This is the list of tasks that we return from the function.</li>
</ul>
<p>A keen eye might note that we also accept a <em>project - task details</em> format for the calendar event subject. When we find one of these we automatically assign it a sub-project name of “Ungrouped” in the task module.</p>
</section>
</section>
<section id="usage" class="level1">
<h1>Usage</h1>
<p>There are only really three parameters that need to be passed to the TimeSheet application to obtain some output: a starting date, an ending date and a user name.</p>
<p>The param module handles the gathering of these values from: the “appsettings.json” file, the “env.private” file or the environment.</p>
<p>Typically the “env.private” file will contain the authentication details (as shown above) and the “appsettings.json” file will hold the UserPrincipalName and so will look like this:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode json code-with-copy"><code class="sourceCode json"><span id="cb8-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb8-2">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"UserPrincipalName"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"john.bates@oldgang.net"</span></span>
<span id="cb8-3"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>If run without any arguments the TimeSheet application will assume a date range that spans the start to the end (inclusive) of the current month. If given a single numeric argument this is interpreted as a number of months back from the current month and the date range that spans that month will be used. So, for example, running:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb9-1">    <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">./TimeSheet</span> 1</span></code></pre></div></div>
<p>will output a timesheet summary for the entire previous month.</p>
<p>The “appsettings.json” file may also contain values for <code>DateFrom</code> and <code>DateTo</code> to overwrite the default values. So, for example, an “appsetting.json” file containing the following would only report on events in my calendar that happened on the first day of November 2023.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode json code-with-copy"><code class="sourceCode json"><span id="cb10-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb10-2">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"UserPrincipalName"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"john.bates@oldgang.net"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb10-3">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"DateFrom"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"1 Nov 2023"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb10-4">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"DateTo"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"2023-11-01"</span></span>
<span id="cb10-5"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>As demonstrated in the above example, any suitably unambiguous DateTime format that can be parsed by the .NET DateTime parser can be used to represent the date range.</p>
<p>These three parameters can also be provided from the environment as environment variables, and on macOS may be prefixed on the command line. For example:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb11-1">    <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">DateFrom</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"1 Nov 2023"</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">DateTo</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"4 Nov 2023"</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">./TimeSheet</span></span></code></pre></div></div>
<p>In spite of all that flexibility, because a time sheet can only be constructed after the event and is most usefully constructed as soon after the event as possible, the most common invocation is:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb12-1">    <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">./TimeSheet</span> 1</span></code></pre></div></div>
<p>to summarise last month’s timesheet.</p>


</section>

 ]]></description>
  <category>Timesheet</category>
  <category>C#</category>
  <category>Microsoft Graph</category>
  <category>Microsoft Outlook</category>
  <category>Microsoft Entra ID</category>
  <guid>https://www.oldgang.net/notebooks/posts/csharp_timesheet/csharp_timesheet.html</guid>
  <pubDate>Fri, 03 Nov 2023 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Error Handling in Go - Some Subtleties</title>
  <dc:creator>John Bates</dc:creator>
  <link>https://www.oldgang.net/notebooks/posts/go_errors/go_errors.html</link>
  <description><![CDATA[ 




<p>As is the case in most other programming languages, good error handling in Go is difficult. In this document I record some of the issues that I have had to address in writing even simple programs.</p>
<section id="responsibility" class="level2">
<h2 class="anchored" data-anchor-id="responsibility">Responsibility</h2>
<p>Consider this simple main function that calls ‘readWorkbook’ to read a workbook from disk into a structure. The function returns two values, a populated workbook structure and a Go error. This is ideomatic go - if a function needs to return an error it is normally passed back as the last returned value.</p>
<p>A nil error is conventionally interpreted to mean that the function worked and so the code will normally check first for a nil error before using the other returned values. In our example, if we know that there is no error we can safely use the other values returned by our function: <code>wb.sheets</code> and <code>wb.name</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode go code-with-copy"><code class="sourceCode go"><span id="cb1-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">package</span> main</span>
<span id="cb1-2"></span>
<span id="cb1-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">import</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb1-4">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"fmt"</span></span>
<span id="cb1-5">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"io"</span></span>
<span id="cb1-6">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"os"</span></span>
<span id="cb1-7">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"strings"</span></span>
<span id="cb1-8"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb1-9"></span>
<span id="cb1-10"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">func</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb1-11">    wbPath <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"./recipies.xlsx"</span></span>
<span id="cb1-12">    wb<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> readWorkbook<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>wbPath<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb1-13">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb1-14">        fmt<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Printf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Error in '%s': %v</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> wbPath<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb1-15">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb1-16">        fmt<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Printf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Read %d sheets from workbook '%s'</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">len</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>wb<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>sheets<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> wb<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb1-17">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb1-18"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>But there is a problem. If recipies.xlsx does not exist in the current directory we get:</p>
<pre><code>Error in './recipies.xlsx': open ./recipies.xlsx: no such file or directory</code></pre>
<p>The caller has no way of knowing that the called function is going to return the name of the file in ‘err’. Or, rather, in all of its potential error messages.</p>
<p>Our added message is also somewhat misleading. We say that there was an error ‘in’ the file, but the error in this case was in opening the file and had nothing to do with the contents of this file.</p>
<p>All of this suggests that we might be better off pushing the reporting of the filename up into the readWorkbook function.</p>
<p>This is the original definition of readWorkbook.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode go code-with-copy"><code class="sourceCode go"><span id="cb3-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">type</span> workbook <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-2">    name   <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">string</span></span>
<span id="cb3-3">    sheets <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]*</span>sheet</span>
<span id="cb3-4"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-5"></span>
<span id="cb3-6"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">type</span> sheet <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-7">    name <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">string</span></span>
<span id="cb3-8">    rows <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]*</span>row</span>
<span id="cb3-9"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-10"></span>
<span id="cb3-11"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">type</span> row <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">struct</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-12">    cells <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">string</span></span>
<span id="cb3-13"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-14"></span>
<span id="cb3-15"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">func</span> readWorkbook<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>name <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">string</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(*</span>workbook<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">error</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-16">    file<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> os<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Open<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-17">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-18">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err</span>
<span id="cb3-19">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-20">    bytes<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> io<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>ReadAll<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>file<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-21">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-22">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err</span>
<span id="cb3-23">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-24">    sheets<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> readSheets<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>bytes<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb3-25">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb3-26">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err</span>
<span id="cb3-27">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb3-28">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>workbook<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> sheets<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span></span>
<span id="cb3-29"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>We can see that the library function os.Open is able to return the filename in its error message but io.ReadAll and readSheets will know nothing about the filename.</p>
<p>If we push the responsibility for adding the workbook name up into the readWorkbook function we get:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode go code-with-copy"><code class="sourceCode go"><span id="cb4-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">func</span> main<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">()</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb4-2">    wbPath <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"./recipies.xlsx"</span></span>
<span id="cb4-3">    wb<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> readWorkbook<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>wbPath<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb4-4">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb4-5">        fmt<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>err<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb4-6">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">else</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb4-7">        fmt<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Printf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Read %d sheets from workbook '%s'</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">len</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>wb<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>sheets<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> wb<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb4-8">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb4-9"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb4-10"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">...</span></span>
<span id="cb4-11"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">func</span> readWorkbook<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>name <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">string</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(*</span>workbook<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">error</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb4-12">    fail <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">func</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>op <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">string</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">error</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(*</span>workbook<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">error</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb4-13">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> fmt<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Errorf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"read work book (%s): %w"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> op<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb4-14">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb4-15">    file<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> os<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Open<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb4-16">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb4-17">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> fail<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"open"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb4-18">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb4-19">    bytes<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> io<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>ReadAll<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>file<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb4-20">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb4-21">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> fail<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"read "</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb4-22">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb4-23">    sheets<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> readSheets<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>bytes<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb4-24">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb4-25">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> fail<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sheets "</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb4-26">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb4-27">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>workbook<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> sheets<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span></span>
<span id="cb4-28"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>Which, assuming that readSheets can return us a “bad format” error message, will give us error messages like this:</p>
<pre><code>read work book (open): open ./recipies.xlsx: no such file or directory
read work book (sheets ./recipies.xlsx): bad format</code></pre>
<p>These don’t repeat the filename but do allow us to determine the location and kind of the error as well as passing the low level error detail back.</p>
<p>The ‘%w’ verb in the format string passed to fmt.Errorf in fail causes the original error to be wrapped inside the new error such that it can be unwrapped when the chain of errors is displayed later.</p>
<p>This change has resulted in a slightly messier readWorkbook function but our calling function has been simplified and, by pushing the error message generation as far up the stack as we can, we have eliminated the chance of duplicating information in the error message, simplified the calling code and so reduced the work required at other sites that might call readWorkbook.</p>
<p>In the article <a href="https://go.dev/blog/error-handling-and-go">Error handling and Go</a> on the <a href="https://go.dev/blog">Go Blog</a> Andrew Gerrand writes that</p>
<p><em>“It is the error implementation’s responsibility to summarize the context.”</em></p>
<p>I interpret that, in this context, as meaning that we should aim to construct the error message as close to the cause of the error as is possible whilst still being able to retain as much of the context as it is required to keep.</p>
</section>
<section id="traceability" class="level2">
<h2 class="anchored" data-anchor-id="traceability">Traceability</h2>
<p>The <a href="https://google.github.io/styleguide/go/decisions.html#error-strings">Google Style Guide for Go</a> says that;</p>
<p><em>Error strings should not be capitalized (unless beginning with an exported name, a proper noun or an acronym) and should not end with punctuation. This is because error strings usually appear within other context before being printed to the user.</em></p>
<p>This context is what helps the reader of the error message understand more about the route through the code that arrived at the error.</p>
<p>From our example error message (above):</p>
<p><code>read work book (open): open ./recipies.xlsx: no such file or directory</code></p>
<p>As we read from left to right, we home in on the source of the actual error. Here, we might infer that in attempting to read a workbook, the open operation of <code>./recipies.xlsx</code> failed with a <code>no such file or directory</code> error from the operating system.</p>
<p>To a user of the software this might be sufficient to help them work out how to resolve the problem. However, a software developer will usually want more traceability. The Go language makes it easy to construct error messages that carry much more detail, but one nice package that does this for us is the <a href="https://github.com/go-errgo/errgo/tree/v2">errgo</a> package developed by Roger Peppe.</p>
<p>Errgo will trace the chain of error returns from its source to the function in which the details of the error are presented. It does this by wrapping the original error with source file and line number information at each point that the error gets returned by a function. This is best seen by example.</p>
<p>Consider the rest of the workbook example, now modified to use errgo. The fail function in readWorkbook now uses errors.Notef to wrap the underlying error.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode go code-with-copy"><code class="sourceCode go"><span id="cb6-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">func</span> readWorkbook<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>name <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">string</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(*</span>workbook<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">error</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-2">    fail <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">func</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>op <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">string</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">error</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(*</span>workbook<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">error</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-3">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> errors<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Notef<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>err<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"read work book (%s)"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> op<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb6-4">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb6-5">    file<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> os<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Open<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb6-6">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-7">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> fail<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"open"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb6-8">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb6-9">    bytes<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> io<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>ReadAll<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>file<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb6-10">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-11">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> fail<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"read "</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb6-12">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb6-13">    sheets<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> readSheets<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>bytes<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb6-14">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-15">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> fail<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sheets "</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb6-16">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb6-17">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>workbook<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> sheets<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">},</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span></span>
<span id="cb6-18"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb6-19"></span>
<span id="cb6-20"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">func</span> readSheets<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>bytes <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">byte</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">([]*</span>sheet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">error</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-21">    sr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> NewSheetReader<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>bytes<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb6-22">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-23">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> errors<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Wrap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>err<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb6-24">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb6-25">    sheets <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]*</span>sheet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb6-26">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> bytes <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">range</span> sr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-27">        rows<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> readRows<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>bytes<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb6-28">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-29">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> errors<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Wrap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>err<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb6-30">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb6-31">        sheets <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">append</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>sheets<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>sheet<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> rows<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">})</span></span>
<span id="cb6-32">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb6-33">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> sheets<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span></span>
<span id="cb6-34"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb6-35"></span>
<span id="cb6-36"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">func</span> readRows<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>bytes <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">byte</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">([]*</span>row<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">error</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-37">    rr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> NewRowReader<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>bytes<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb6-38">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-39">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> errors<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Wrap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>err<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb6-40">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb6-41">    rows <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]*</span>row<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb6-42">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> _<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> bytes <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">range</span> rr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-43">        cells<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> readCells<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>bytes<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb6-44">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-45">            <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> errors<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Wrap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>err<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb6-46">        <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb6-47">        rows <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">append</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>rows<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>row<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span>cells<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">})</span></span>
<span id="cb6-48">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb6-49">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> rows<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span></span>
<span id="cb6-50"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb6-51"></span>
<span id="cb6-52"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">func</span> readCells<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>bytes <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">byte</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">([]</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">string</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">error</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-53">    cr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> NewCellReader<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>bytes<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb6-54">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-55">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> errors<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Wrap<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>err<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb6-56">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb6-57">    cells <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">string</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb6-58">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> _<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> s <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">range</span> cr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-59">        cells <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">append</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>cells<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> s<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb6-60">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb6-61">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> cells<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span></span>
<span id="cb6-62"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb6-63"></span>
<span id="cb6-64"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// NewSheetReader splits the 'bytes' that make up a workbook</span></span>
<span id="cb6-65"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// into a map of bytes that make up each sheet indexed by sheet name.</span></span>
<span id="cb6-66"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// This implementation hardwires the worksheet.</span></span>
<span id="cb6-67"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">func</span> NewSheetReader<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>bytes <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">byte</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">map</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">string</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">][]</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">byte</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">error</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-68">    sheets <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">map</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">string</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">][]</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">byte</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-69">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Sheet1"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">byte</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"A1,B1/A2,B2,C2/A3"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span></span>
<span id="cb6-70">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Sheet2"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">byte</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"A1"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span></span>
<span id="cb6-71">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb6-72">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> sheets<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span></span>
<span id="cb6-73"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb6-74"></span>
<span id="cb6-75"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// NewRowReader splits the 'bytes' that make up a sheet</span></span>
<span id="cb6-76"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// into a slice of bytes that make up each row.</span></span>
<span id="cb6-77"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">func</span> NewRowReader<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>bytes <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">byte</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">([][]</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">byte</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">error</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-78">    rowstrings <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> strings<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Split<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">string</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>bytes<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"/"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb6-79">    rows <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[][]</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">byte</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{}</span></span>
<span id="cb6-80">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> _<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> row <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">range</span> rowstrings <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-81">        rows <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">append</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>rows<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">byte</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>row<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">))</span></span>
<span id="cb6-82">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb6-83">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">true</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// force an error here</span></span>
<span id="cb6-84">        <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> errors<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>New<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"bad format row"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb6-85">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb6-86">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> rows<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span></span>
<span id="cb6-87"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb6-88"></span>
<span id="cb6-89"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// NewCellReader splits the 'bytes' that make up a row</span></span>
<span id="cb6-90"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// into a slice of strings that make up each row.</span></span>
<span id="cb6-91"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">func</span> NewCellReader<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>bytes <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">byte</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">([]</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">string</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">error</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb6-92">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> strings<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Split<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">string</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>bytes<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">","</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span></span>
<span id="cb6-93"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>The readSheets, readRows and readCells functions now call errors.Wrap with an error before passing the result back down the call stack. The effect of this is to have information about the source code file and line number added to the error as it is passed down through each function.</p>
<p>For the purposes of generating an error message we have introduced a fictional “bad format row” error in the NewRowReader function.</p>
<p>If in the code where we display the error message we use</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode go code-with-copy"><code class="sourceCode go"><span id="cb7-1">fmt<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Printf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"%#v"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span></code></pre></div></div>
<p>in place of:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode go code-with-copy"><code class="sourceCode go"><span id="cb8-1">fmt<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>err<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span></code></pre></div></div>
<p>Then rather than our simple error message of:</p>
<pre><code>read work book (sheets ./recipies.xlsx): bad format row</code></pre>
<p>instead we see:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode json code-with-copy"><code class="sourceCode json"><span id="cb10-1"><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span></span>
<span id="cb10-2">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span><span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">/Users/john/Projects/GoErrors/main.go</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">44</span><span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">:</span> <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">read</span> <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">work</span> <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">book</span> <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">(sheets</span> <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">./recipies.xlsx)</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb10-3">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span><span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">/Users/john/Projects/GoErrors/main.go</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">71</span><span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">:</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb10-4">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span><span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">/Users/john/Projects/GoErrors/main.go</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">81</span><span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">:</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb10-5">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span><span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">/Users/john/Projects/GoErrors/main.go</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">126</span><span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">:</span> <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">bad</span> <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">format</span> <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">row</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb10-6"><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span></span></code></pre></div></div>
<p>Which gives us a traceable route through our code starting at line 44 in main.go and progressing through lines 71 and 81 to line 126 which is where the error was generated.</p>
<p>Errgo maintains both the normal error message and a detailed stack trace which can be of great diagnostic use to a developer. The programmer needs to devise a mechanism that prevents a user from seeing the detailed message but which allows the developer access - typically this might be through a log file.</p>
</section>
<section id="fragile-dependencies" class="level2">
<h2 class="anchored" data-anchor-id="fragile-dependencies">Fragile Dependencies</h2>
<p>The fmt.Errorf function from the <code>fmt</code> package in the Go standard library can be used to create a new error that wraps an existing error:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode go code-with-copy"><code class="sourceCode go"><span id="cb11-1">fmt<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Errorf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"read work book (%s): %w"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> op<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span></code></pre></div></div>
<p>When we do this the format of the new error message is controlled by the format string passed to fmt.Errorf in its first argument. Typically, perhaps ideomatically, the message from the underlying error follows the new error message by a colon and a space, as above.</p>
<p>However, the action of wrapping an error does more than just augment an error message, it also makes the actual underlying error available to any function receiving the new error.</p>
<p>Suppose we make a call to os.Open to open an operating system file. In checking for an error we might either choose to return the error we received from os.Open or we might choose to wrap it in another message and return the wrapped error, as here:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode go code-with-copy"><code class="sourceCode go"><span id="cb12-1">file<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> os<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Open<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>name<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb12-2"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb12-3">    err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> fmt<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Errorf<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"open file: %w"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> op<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb12-4">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> err</span>
<span id="cb12-5"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>In this situation the calling code has access to the original error, including the name of the file that we attempted to open.</p>
<p>The system library function errors.As can be used to interrogate the stack of wrapped errors to see if it contains errors of a particular kind. For example, if an error occurs in a call to the system library function os.Open then the error that is returned will be of type *os.PathError. No matter how deep the stack of wrapped errors, a call to errors.As can be used to extract the PathError and its values.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode go code-with-copy"><code class="sourceCode go"><span id="cb13-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">var</span> perr <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>fs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>PathError</span>
<span id="cb13-2"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> errors<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>As<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>err<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span>perr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb13-3">    fmt<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Println<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"err"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> perr<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Path<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb13-4"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>This might not always be desirable. For example, if you are writing an API you will not want to leak what might be seen as implementation detail out into errors that users of the API might choose to rely on.</p>
<p>The errgo package takes a tougher stance on the construction of the wrapped error stack. If an error is wrapped by the errgo package using, say, either errors.Notef or errors.Wrap as above, then calls to the system library errors.Is and errors.As functions will always return false and so no such interrogation will be possible.</p>
<p>If a function wishes to return information about an error and its cause then it has to be quite specific about how it constructs that error. It can make use of the second argument to errors.Notef to specify which types of error can be exposed as a cause of the error, for example:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode go code-with-copy"><code class="sourceCode go"><span id="cb14-1">fail <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">func</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>op <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">string</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">error</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(*</span>workbook<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">error</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb14-2">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> errors<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Notef<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb14-3">        err<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb14-4">        errors<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Is<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>fs<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>ErrNotExist<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">),</span></span>
<span id="cb14-5">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"read work book (%s)"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb14-6">        op<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb14-7">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb14-8"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>Alternatively it can make use of the errors.Becausef function to explicitly supply the cause of the error (in the second argument to errors.Becausef).</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb15" style="background: #f1f3f5;"><pre class="sourceCode go code-with-copy"><code class="sourceCode go"><span id="cb15-1">fail <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">func</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>op <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">string</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">error</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(*</span>workbook<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">error</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb15-2">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">return</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> errors<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Becausef<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span></span>
<span id="cb15-3">        err<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb15-4">        err<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb15-5">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"read work book (%s)"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb15-6">        op<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb15-7">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb15-8"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>In this example, as well as wrapping the underlying error and adding our own message, we have supplied the underlying error as the cause of the error. By doing this, we have allowed code lower down the call stack to examine the cause of the error by calling the errors.Cause function.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb16" style="background: #f1f3f5;"><pre class="sourceCode go code-with-copy"><code class="sourceCode go"><span id="cb16-1">wb<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> readWorkbook<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>wbPath<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb16-2"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">nil</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb16-3">    cause <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:=</span> errors<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span>Cause<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">(</span>err<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span>
<span id="cb16-4">    <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> cause <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> err <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb16-5">        <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// do something with the cause.</span></span>
<span id="cb16-6">    <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb16-7"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div></div>
<p>If there has been no explicit cause assigned to the error then <code>errors.Cause(err)</code> will return its argument, otherwise it will return the cause of the error. Errgo allows us to both construct an error chain and also to preserve the original cause of an error.</p>
<p>Only the errors.Note, errors.Notef, errors.Because and errors.Becausef functions preserve the error cause - Errors.Wrap does not preserve the original cause of an error. This arrangement makes it less easy to accidentally pass information down the error chain about an implementation detail that code lower down might become dependent on.</p>


</section>

 ]]></description>
  <category>Go</category>
  <category>Error Handling</category>
  <guid>https://www.oldgang.net/notebooks/posts/go_errors/go_errors.html</guid>
  <pubDate>Fri, 08 Sep 2023 00:00:00 GMT</pubDate>
</item>
<item>
  <title>The Strange Lure of J</title>
  <dc:creator>John Bates</dc:creator>
  <link>https://www.oldgang.net/notebooks/posts/the_lure_of_j/the_lure_of_j.html</link>
  <description><![CDATA[ 




<p>It is a good idea for a developer to experience a number of programming languages. With the learning of each new language comes a new competence. For me, after many years of programming in only imperative programming languages, some exposure to OCAML and the F# language taught me lessons that I wish I had known at the start of my career.</p>
<p>Last December I read a document on the <a href="https://www.jsoftware.com">J Programming Language</a>. I don’t even remember where I found it but it lead me to the <a href="https://code.jsoftware.com/wiki/Books">books</a> section of the J Software website and, before I knew it, I was <a href="https://code.jsoftware.com/wiki/System/Installation#Overview">installing</a> the software.</p>
<p>J is a flavour of <a href="https://en.wikipedia.org/wiki/APL_(programming_language)">APL</a> which was developed at IBM in the 1960s. One notable feature of APL was that it used symbols to represent the core functions and operators in the language and this meant that a new vocabulary needed to be learnt even to read APL code.</p>
<p>J was developed in the early 1990s by Ken Iverson and Roger Hui. Ken Iverson was the original inspiration behind APL. J is an array programming language, based on APL, but has the advantage to a programmer of using the ascii character set.</p>
<p>In preserving its similarity to APL, the symbols of APL are represented in J as one or two-character words, most commonly involving punctuation characters, occasionally paired with lower or upper case letters. This has the effect of making J a very terse language. Combine that with the way in which many of the components of the language can be composed with one another to form more complex operations and the language can be a challenge to read - even thought the ASCII character set is used.</p>
<p>For example, the modifier <code>/</code> can be combined with another verb, say <code>+</code> to produce a new verb that applies <code>+</code> between all of its operands. So</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb1-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">+/</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span></span>
<span id="cb1-2"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">15</span></span></code></pre></div></div>
<p>is equivalent to</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb2-1"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span></span>
<span id="cb2-2"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">15</span></span></code></pre></div></div>
<p>We could combine it with the verb <code>&gt;.</code>, which returns the larger of its two arguments, so that the new verb <code>&gt;./</code> is the J equivalent of the function <code>max(x)</code> where <code>x</code> is a list of numbers.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb3-1"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">&gt;.</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span></span>
<span id="cb3-2"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span></span>
<span id="cb3-3"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">&gt;.</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span></span>
<span id="cb3-4"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span></span></code></pre></div></div>
<p>So that,</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb4-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">&gt;./</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span></span>
<span id="cb4-2"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span></span></code></pre></div></div>
<p>is equivalent to</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb5-1"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">&gt;.</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">&gt;.</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">&gt;.</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">&gt;.</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span></span>
<span id="cb5-2"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span></span></code></pre></div></div>
<p>I found myself working my way through the introductory <a href="https://www.jsoftware.com/help/learning/contents.htm">Learning J</a> by Roger Stokes and the more challenging <a href="https://www.jsoftware.com/help/jforc/contents.htm">J for C Programmers</a> by Henry Rich which is also available as a downloadable PDF <a href="https://code.jsoftware.com/wiki/Guides/Getting_Started">here</a>. All the time I needed to make reference to the J <a href="https://code.jsoftware.com/wiki/NuVoc">NuVoc</a> vocabulary cheat sheet which contains links to full descriptions of each of the monadic and dyadic forms of the various J verbs, adverbs and conjunctions.</p>
<p>The strange thing was that, for the best part of two months, I found it very hard to put these books down. The going was difficult, but there was something very addictive about the challenge of completing a chapter and understanding the lessons and examples in it.</p>
<p>Two months later, I didn’t feel as though I could call myself a J programmer but I did notice that I was able to, at least, visually parse some of the more complex lines of J, and I knew where to look to find the definition of a particular verb.</p>
<section id="grammar" class="level3">
<h3 class="anchored" data-anchor-id="grammar">Grammar</h3>
<p>It makes sense to define a little (simplified) J grammar at this point. What we might commonly call a statement in other languages is referred to in J as a sentence. The executable bits of a sentence are called fragments. A noun holds data. A verb operates on one or two nouns to produce another noun. An adverb operates on a verb to produce another verb.</p>
<p>Evaluation of a sentence is the right-to-left evaluation of the fragments of the sentence, with the result of evaluating a fragment replacing the fragment itself and being passed as an operand to the next fragment.</p>
<p>We saw, above, an example of an adverb <code>/</code> which modified the <code>+</code> verb to produce a new verb <code>+/</code> which would sum the argument on its right.</p>
</section>
<section id="a-simple-program" class="level3">
<h3 class="anchored" data-anchor-id="a-simple-program">A Simple Program</h3>
<p>I decided that it was time to write a simple J program, or, rather, to attempt a challenge of sorts. I had been inspired by Rob Pike’s <a href="https://github.com/robpike/ivy">Ivy</a> - an APL-like calculator, and in particular, by Russ Cox’s <a href="https://www.youtube.com/playlist?list=PLrwpzH1_9ufMLOB6BAdzO08Qx-9jHGfGg">YouTube Videos</a> of his solutions to the first fourteen days of the <a href="https://adventofcode.com/2021">Advent of Code 2021</a> challenges.</p>
<p>My program was going to be somewhat simpler though. I wanted to see how J would compare with a .NET language like F# for simple list manipulation. So I decided on a simple list of tasks, starting with a function to display the contents of a list.</p>
<section id="program-parts" class="level4">
<h4 class="anchored" data-anchor-id="program-parts">Program Parts</h4>
<ol type="1">
<li><p>Write a function, <code>outArray</code> that, given a string title and an array of integers as its two parameters, outputs that array as a comma-separated list, preceded by the title, a count of the number of integers in square-brackets and a colon. So called with the parameters <code>"Initial"</code> and <code>1 2 3 4</code> it would return:</p>
<p><code>Initial [4]: 1, 2, 3, 4</code></p></li>
<li><p>Assign a small array of ints, say, the array: 31 5 7 6 3 2 8 to the variable <code>ints</code>.</p></li>
<li><p>Use the <code>outArray</code> function to output the <code>ints</code> array with the title “Initial”.</p></li>
<li><p>Create a new list, <code>sortedInts</code>, from the original <code>ints</code> which contains the same list in ascending order, and output it with the outArray function and the title “Sorted”.</p></li>
<li><p>Create a list, <code>oddInts</code> that contains just those ints from <code>sortedInts</code> that are odd and output it with the title “Odd”.</p></li>
<li><p>Create a list <code>argvInts</code> that has been read from the command line and output it with the title “argvInts”.</p></li>
<li><p>Create a list <code>fileInts</code> that has been read from a file on the filesystem that contains a single line of comma-separated integers and output it with the title “FileInts”.</p></li>
<li><p>Combine the <code>oddInts</code>, <code>argvInts</code>, and <code>fileInts</code> arrays into a single list, <code>combinedInts</code>, without duplicates and output it with the title “CombinedInts”.</p></li>
<li><p>Calculate the average of the numbers in the <code>combinedInts</code> array and store it in the scalar <code>average</code>.</p></li>
<li><p>Split the numbers in the <code>combinedInts</code> array into two distinct arrays, <code>higher</code> and <code>lower</code> such that <code>higher</code> contains those ints that are higher than the value in <code>average</code> and <code>lower</code> contains the remaining ints. Output both <code>higher</code> and <code>lower</code> with `outArray’.</p></li>
</ol>
</section>
<section id="the-outarray-function" class="level4">
<h4 class="anchored" data-anchor-id="the-outarray-function">The OutArray Function</h4>
<p>My initial attempt at a function that could output a list of integers in CSV format using J is almost too embarassing to include in this notebook. Let’s just say that it wasn’t quite a simple as this one:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb6-1">outArray <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span> <span class="re">: 0</span></span>
<span id="cb6-2">  nums <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=:</span> <span class="re">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">' '</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">', '</span><span class="re">)</span> stringreplace <span class="re">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">":</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">y</span><span class="re">)</span></span>
<span id="cb6-3">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">;</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">x;</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'['</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">;</span><span class="re">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">":#y</span><span class="re">)</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">;</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">']: '</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">;</span> nums</span>
<span id="cb6-4"><span class="re">)</span></span></code></pre></div></div>
<p>The discovery of the library function <code>stringreplace</code> made life a lot easier. I have broken the definition up into two lines to make it easier to read but, idiomatic J would probably show it on a single line. Experienced J programmers will probably have to stop reading at this point. I’m sure that a much more elegant implementation would be obvious in hindsight.</p>
<p>Strictly speaking, <code>outArray</code> is not a function but a dyadic verb. What we might call an operator in most languages, that takes two arguments. It is called with a string <code>title</code> as its left argument and a list of integers as its right argument.</p>
<p>To understand a J sentence you have to begin from the right-hand-side, as the language has right-to-left precedence for verbs. So the following expression:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb7-1"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">*</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">+</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span></span>
<span id="cb7-2"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span></span></code></pre></div></div>
<p>evaluates to <code>8</code> rather than the <code>7</code> we might expect in a language that had a hierarchy of operator precedence in which multiplication was applied before addition.</p>
<p>Another factor that can slightly complicate the reading of a J statement, is that most verbs come in two flavours:</p>
<ul>
<li>a monadic form which takes just one argument on the right hand side, and</li>
<li>a dyadic form which takes two arguments, one on each side.</li>
</ul>
<p>If a verb has a noun on its left, it is executed as a dyadic verb with a left and right operand. If a verb does not have a noun on itls left, it is executed as monadic with just a right operand.</p>
<p>Monadic and dyadic verbs have distinct definitions and do not even have to perform the same kind of operation. In general, the dyadic form of a verb performs a variation on the operation that the monadic form performs. For example, when used monadically the verb <code>&lt;.</code> calculates the floor of (greatest integer less than) its operand and when used dyadically it returns the smaller of its two operands.</p>
<p>Even the definition of verbs is syntactically unusual. In the definition above the body of the definition, that gets assigned to <code>outArray</code> is the part between the fragment <code>4 : 0</code> and the line that begins with a <code>)</code> three lines below. The <code>4</code> means that we are defining a dyadic verb and the <code>0</code> means that its definition is to be found in the current document up as far as the line that begins with a right-hand round bracket. It makes for difficult reading at first, but you get used to it, it is well defined and there is a keyword form that means the same thing that you can use if you prefer.</p>
<p>In a dyadic verb definition the left-argument is represented by <code>x</code> and the right-argument by <code>y</code>.</p>
<p>The first line looks like this:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb8-1">nums <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=:</span> <span class="re">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">' '</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">', '</span><span class="re">)</span> stringreplace <span class="re">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">":</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">y</span><span class="re">)</span></span></code></pre></div></div>
<p>We start evaluation with the right-most fragment <code>(": y)</code> which is the verb <code>":</code> applied to the value of y (the right-hand argument of <code>outArray</code>).</p>
<p>The J software website provides a handy cheat sheet, known as <a href="https://code.jsoftware.com/wiki/NuVoc">NuVoc</a>, which contains links to the definitions of all of the major verbs that are built into J.</p>
<p>From NuVoc we can see that our verb <code>":</code> is known as “Default Format” and that it will simply convert our list of integers into a string which contains the integers separated by a space.</p>
<p>So the fragment will be replaced with the string representation of our list and this will become the right-hand argument to <code>stringreplace</code>.</p>
<p>So if we invoked the <code>outArray</code> verb with a right-hand argument of</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb9-1"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span></span></code></pre></div></div>
<p>the first line would, after evaluating its right-most fragment, become:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb10-1">nums <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=:</span> <span class="re">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">' '</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">', '</span><span class="re">)</span> stringreplace <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'1 2 3'</span></span></code></pre></div></div>
<p>The verb <code>stringreplace</code> is a J standard library verb. Its left-argument is a two-column matrix of “old” and “new” replacements. Its right argument is the string in which to make the replacements. The resulting string is returned as the value of evaluating the fragment.</p>
<p>After our string replacements the variable <code>nums</code> will contain a comma separated list of the list of numbers in string format.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb11-1"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span></span></code></pre></div></div>
<p>The second line is less easy on the eye:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb12-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">;</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">x;</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'['</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">;</span><span class="re">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">":#y</span><span class="re">)</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">;</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">']: '</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">;</span> nums</span></code></pre></div></div>
<p>The key to understanding it is to know that the dyadic verb <code>;</code> (known as Link) is being used to join the following nouns:</p>
<ol type="1">
<li>x</li>
<li>‘[’</li>
<li>(“:#y)</li>
<li>‘]:’</li>
<li>nums</li>
</ol>
<p>The first, <code>x</code>, is the left-hand argument to <code>outArray</code> which is the string title we wish to display at the start of the output line.</p>
<p>The second item is a string containing a left-hand square bracket.</p>
<p>The third item has 3 parts:</p>
<ol type="1">
<li>The monadic verb <code>":</code> (known as Default Format) which converts an integer to its string representation.</li>
<li>The monadic verb <code>#</code> (known as Tally) which counts the items in its argument.</li>
<li><code>y</code> which is the right-hand argument to <code>outArray</code> and is our original list of integers.</li>
</ol>
<p>We evaluate these verbs from right to left which means that we apply Tally to count the items in our integer list first. If, for example, the list was <code>1 2 3 4</code> then the count returned by Tally would be 4. We then use Default Format to convert that count to a string because, in J, type conversions do not happen automatically and we want to link string values together with our Link verb.</p>
<p>The fourth item is a string containing a right-hand square bracket, a colon and a space.</p>
<p>The fifth item is <code>nums</code> our string representation of the integer list.</p>
<p>Our verb, Link, joins all of these together into what is known as a list of boxed items.</p>
<p>Then finally, represented by the first semi-colon character on the line, the monadic verb <code>;</code> (known as Raze) removes the level of boxing that was previously applied by Link and runs the results together without spaces into a single string.</p>
</section>
<section id="assignment-and-output" class="level4">
<h4 class="anchored" data-anchor-id="assignment-and-output">Assignment and Output</h4>
<p>There are two kinds of assignment verb in J. Local assignment <code>=.</code> and global assignment <code>=:</code>. Local assignment can be used to create a noun, adverb or verb that hides any global with the same name for the duration of the containing verb definition or script. On termination of execution of the verb or script the previous value is reinstated.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb13-1">ints <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">31</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span></span>
<span id="cb13-2"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Initial'</span> outArray ints</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb14-1">Initial<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>]<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">31</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span></span></code></pre></div></div>
<p>We use global assignment to create the verb <code>ints</code> to hold a list of integers. And we output it with a call to our dyadic verb <code>outArray</code> passing its two arguments on the left and right hand side: <code>'Initial'</code> and <code>ints</code>.</p>
</section>
<section id="sort-the-list" class="level4">
<h4 class="anchored" data-anchor-id="sort-the-list">Sort the List</h4>
<p>Sorting in J is performed by the built-in verbs <code>/:</code> and <code>\:</code>. These are known as <code>Grade Up</code> and <code>Grade Down</code> when used monadically and <code>Sort Up</code> and <code>Sort Down</code> when used dyadically. To understand <code>Sort Up</code> you need to first understand <code>Grade Up</code>.</p>
<p>When applied to a list of atoms (integers in our case), <code>Grade Up</code> returns the permutation of those atoms that will result in them being sorted into ascending order. The permutation is the list of indexes into the original list that, were items to be selected according to those indexes, would result an ascending list of the atoms. (Indexes in J are 0-based.)</p>
<p>For example, the Grade Up permutation of the list <code>5 3 4</code> is the list <code>1 2 0</code>:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb15" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb15-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">/:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span></span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb16" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb16-1"><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span></span></code></pre></div></div>
<p>The permutation tells us to first take the atom at index 1 in the original list (<code>3</code>), then the atom at index 2 (<code>4</code>), then the atom at index 0 (<code>5</code>) - giving us the expected list <code>3 4 5</code>.</p>
<p>Used dyadically, the <code>/:</code> verb is known as <code>Sort Up</code>. When given arguments <code>x</code> and <code>y</code> the result of <code>x /: y</code> is to sort <code>x</code> using the order given by <code>y</code>. In other words, it applies to list <code>x</code> the permutation that sorts list <code>y</code> into ascending order.</p>
<p>And so, if <code>x</code> and <code>y</code> are the same thing the return value is that of <code>x</code> sorted into ascending order.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb17" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb17-1">sortedInts <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=:</span> ints <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">/:</span> ints</span>
<span id="cb17-2"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Sorted'</span> outArray sortedInts</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb18" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb18-1">Sorted<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span>]<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">31</span></span></code></pre></div></div>
<p>We obtain a sorted list by invoking <code>Sort Up</code> with our <code>ints</code> list passed as both left and right arguments. We store the result in <code>sortedInts</code> for later use.</p>
</section>
<section id="select-the-odd-integers" class="level4">
<h4 class="anchored" data-anchor-id="select-the-odd-integers">Select the Odd Integers</h4>
<p>We can create a list containing only the odd integers from a list by making use of two J verbs: the dyadic form of the verb <code>#</code> (known as <code>Copy</code>) and the dyadic form of the verb <code>|</code> (known as <code>Residue</code>).</p>
<p>When called with arguments <code>x</code> and <code>y</code> the value of <code>x # y</code> is a new array in which each integer in <code>x</code> determines how many times the corresponding item of <code>y</code> appears. For example:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb19" style="background: #f1f3f5;"><pre class="sourceCode y code-with-copy"><code class="sourceCode yacc"><span id="cb19-1">3 1 0 2 # 6 7 8 9</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb20" style="background: #f1f3f5;"><pre class="sourceCode y code-with-copy"><code class="sourceCode yacc"><span id="cb20-1">6 6 6 7 9 9</span></code></pre></div></div>
<p>Resulting in 3 sixes, 1 seven, 0 eights and 2 nines. So, in order to pluck the odd numbers from a list (our <code>y</code> argument to <code>Copy</code>) we could use a left argument that contained a one in each position in which an odd number appeared and a zero in each position that an even number appeared.</p>
<p>The verb <code>Residue</code> will create such a list. The expression <code>x | y</code>, returns the remainder when dividing an integer in <code>y</code> by the corresponding integer in <code>x</code>. If the list <code>x</code> consists of just a single integer then it will return the remainder of dividing every integer in <code>y</code> by the single integer in <code>x</code>. So the expression <code>2 | y</code> will return an array, the same length as <code>y</code>, which contains a one in every position where the corresponding integer in <code>y</code> is odd and a zero in every position where the corresponding integer is even.</p>
<p>Combining these two and remembering that J has right to left evaluation, and so bracketing to obtain the desired effect, we get:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb21" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb21-1">oddInts <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=:</span> <span class="re">(</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">|</span> sortedInts<span class="re">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">#</span> sortedInts</span>
<span id="cb21-2"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Odd'</span> outArray oddInts</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb22" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb22-1">Odd<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>]<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">31</span></span></code></pre></div></div>
</section>
<section id="read-from-the-environment" class="level4">
<h4 class="anchored" data-anchor-id="read-from-the-environment">Read from the Environment</h4>
<p>The next part of the program was to read a list of integers from the environment. I’ve not attempted to read from the environment in this notebook but, instead, simulate the environment to show how it would be done.</p>
<p>In a J script, the system variable <code>ARGV_z_</code> would contain a list of strings (character arrays in J) with the name of the program at the head of the list and the arguments, as character arrays, in the rest of the list.</p>
<p>The assignment to <code>ourArgv</code> below uses the dyadic form of the verb <code>;</code> (<code>Link</code>) to join a number of strings together into a list of boxed items to simulate the effect of a real <code>ARGV_z_</code> array.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb23" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb23-1">ourArgv <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'programName'</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">;</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'33'</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">;</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'44'</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">;</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'55'</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">;</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'66'</span></span>
<span id="cb23-2">argvInts <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">".</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">}.</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">&gt;</span> ourArgv</span>
<span id="cb23-3"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'ArgvInts'</span> outArray argvInts</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb24" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb24-1">ArgvInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>]<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">33</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">44</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">55</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">66</span></span></code></pre></div></div>
<p>This right hand side of the assignment to <code>argvInts</code> contains three verbs and a noun. The noun <code>ourArgv</code> is simulating the system noun (<code>ARGV_z_</code>) which contains a boxed array of the arguments that were provided to the program.</p>
<p>The verb <code>&gt;</code> does not have a noun to its left and so its monadic form (<code>Open</code>) is used. The effect of this is to un-box the array of arguments. However, the first atom in this list is always the name of the program, and we want to discard that.</p>
<p>The verb <code>}.</code> does not have a noun as its left argument so the monadic form of <code>}.</code> (<code>Behead</code>) is used. The action of <code>Behead</code> is to drop the leading item from its argument and return the rest of the array. This has the desired effect of leaving us with an array, each entry of which is itself a character array representing an integer. We can convert these character arrays into integers using the monadic version of <code>".</code> (<code>Do</code>). The effect of <code>Do</code> is to execute each of the strings, replacing them with the result of the execution which, in this case, is their integer representation.</p>
</section>
<section id="read-from-a-file" class="level4">
<h4 class="anchored" data-anchor-id="read-from-a-file">Read from a File</h4>
<p>Working from the right hand side of the expression that is assigned to <code>fileInts</code>. We read a list of integers from a file in which they are stored (separated by commas). To do this we make use of the monadic form of the system verb <code>freads</code>. This reads the file whose path is given by the contents of its argument <code>F</code> and returns it as a string.</p>
<p>This string (in our file) will contain a final linefeed character and so we use the verb <code>}:</code> (<code>Curtail</code>) to drop it and return just the file contents.</p>
<p>The dyadic verb <code>,</code> (<code>Append</code>) is used, with the single character <code>','</code> as its left argument and our string from the file as its right argument to join the two together - effectively prepending a single comma character to the beginning of the string that has been read from the file.</p>
<p>So far we have a single string containing our integers, each separated with a comma and with a single comma character at the start of the string. We operate on this string using the adverb <code>;._1</code> (<code>Cut</code>). This is one of the family of <code>Cut</code> adverbs and this one will cut up a string into an array using the first character of the string to indicate the cut points, and removing all of the cut points from the resulting array. The first character of our string is a comma, and so the string gets converted into an array of strings, each representing one of the numbers in our comma-separated-variable file.</p>
<p>Finally, we apply the monadic verb <code>".</code> (<code>Do</code>) to the array of strings to convert it into an array of integers.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb25" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb25-1">F <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'/Users/john/j903-user/projects/intarray/fileints.csv'</span></span>
<span id="cb25-2">fileInts <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">".;.</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">_1</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">','</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">}:</span> freads F</span>
<span id="cb25-3"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'FileInts'</span> outArray fileInts</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb26" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb26-1">FileInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4</span>]<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span></span></code></pre></div></div>
<p>We assign the resulting integer array to <code>fileInts</code>.</p>
</section>
<section id="combine-without-duplicates" class="level4">
<h4 class="anchored" data-anchor-id="combine-without-duplicates">Combine without Duplicates</h4>
<p>We now need to combine the three arrays: <code>oddInts</code>, <code>argvInts</code> and <code>fileInts</code> into a single array of integers without retaining duplicates.</p>
<p>J makes this very easy for us. We use the dyadic <code>,</code> (<code>Append</code>) to combine the three arrays into a single array. The we use the monadic verb <code>~.</code> (<code>Nub</code>) to remove any item of an array that matches a preceding item - i.e.&nbsp;to remove duplicates.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb27" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb27-1">combinedInts <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">~.</span> oddInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> argvInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> fileInts </span>
<span id="cb27-2"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'CombinedInts'</span> outArray combinedInts</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb28" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb28-1">CombinedInts<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">11</span>]<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">31</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">33</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">44</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">55</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">66</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span></span></code></pre></div></div>
<p>We assign the resulting list, now free of duplicates, to <code>combinedInts</code>.</p>
</section>
<section id="calculate-the-average" class="level4">
<h4 class="anchored" data-anchor-id="calculate-the-average">Calculate the Average</h4>
<p>Next we need to calculate the average of our combined list.</p>
<p>When three verbs occur one after another in a sequence, <code>(f g h)</code> and if <code>f</code> is monadic, <code>g</code> is dyadic and <code>h</code> is monadic, this is known as a <em>fork</em>. This pattern occurs commonly enough for it to be recognised as a special case in J. A monadic fork with a single right hand side argument <code>y</code>, say, has the following interpretation:</p>
<ul>
<li><code>(f g h) y</code> means <code>(f y) g (h y)</code></li>
</ul>
<p>So, the noun <code>y</code> is first supplied to the monadic verb <code>h</code>, then to the monadic verb <code>f</code> and then the results of those computations are provided to the dyadic verb <code>g</code> as its right and left arguments respectively.</p>
<p>To calculate an average from our list of integers we employ a fork made up of the following verbs:</p>
<ol type="1">
<li><code>+/</code> A monadic verb that calculates the sum of the items in its argument.</li>
<li><code>%</code> (<code>Divide</code>) A dyadic verb that divides its left argument by its right argument.</li>
<li><code>#</code> (<code>Tally</code>). A monadic verb that counts the number of items in its argument.</li>
</ol>
<p>So, in the assignment to <code>average</code> below we have a fork <code>(+/ % #)</code> in which <code>+/</code> plays the role of <code>f</code>, <code>Divide</code> plays the role of <code>g</code> and <code>Tally</code> plays the role of <code>h</code>.</p>
<p>When supplied the argument <code>combinedInts</code> represented by <code>y</code>, <code>(f g h) y</code> becomes:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb29" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb29-1"><span class="re">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">+/</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">%</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">#</span><span class="re">)</span> combinedInts</span></code></pre></div></div>
<p>Which expands to</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb30" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb30-1"><span class="re">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">+/</span> combinedInts<span class="re">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">%</span> <span class="re">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">#</span> combinedInts<span class="re">)</span></span></code></pre></div></div>
<p>Or, in plain words, we calculate the sum of the integers in <code>combinedInts</code> and divide it by a count of the number of integers in <code>combinedInts</code> which, of course, gives us an average.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb31" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb31-1">average <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=:</span> <span class="re">(</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">+/</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">%</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">#</span><span class="re">)</span> combinedInts</span>
<span id="cb31-2"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Average'</span> outArray average</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb32" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb32-1">Average<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>]<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">24.9091</span></span></code></pre></div></div>
<p>Which looks to be of the right size.</p>
</section>
<section id="split-into-higher-and-lower-lists" class="level4">
<h4 class="anchored" data-anchor-id="split-into-higher-and-lower-lists">Split into Higher and Lower Lists</h4>
<p>The last part of the program is to split the <code>combinedInts</code> array into two distinct arrays with one containing all of the integers that are higher than the average and the other containing the remaining integers.</p>
<p>The dyadic verb <code>&gt;</code> (<code>Greater</code>), given an array of integers as its left argument and a number as its right argument produces an array of zeroes and ones of the same length as its left argument and containing a one in every position where the item in the left argument array is greater than the number given as the right argument. So, for example, <code>3 5 2 &gt; 4</code> returns the array <code>0 1 0</code>.</p>
<p>We can use the conjunction <code>&amp;</code> (<code>Bond</code>) to attach a value to the right or left argument of a dyadic verb to produce a monadic verb with a bound argument. So the expression <code>(&gt;&amp;average)</code> is a monadic verb that returns an array of zeroes and ones according as the items in the array passed as its argument have a value greater than the value of <code>average</code>.</p>
<p>So if <code>average</code> has the value 24.9091 then <code>(&gt;&amp;average) 23 24 25</code> will return <code>0 0 1</code>.</p>
<p>As we did earlier, in our calculation of the odd numbers in a list, we can make use of the dyadic <code>#</code> (<code>Copy</code>) to select only those items in <code>combinedInts</code> which are greater in value than <code>average</code>. We assign those integers to the <code>higher</code> array.</p>
<p>We then use the <code>-.</code> verb (<code>Less</code>) which, when left and right arguments are lists, returns all of the items in the left argument that are not in the right argument.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb33" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb33-1">higher <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=:</span> <span class="re">((</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">&gt;&amp;</span>average<span class="re">)</span> combinedInts<span class="re">)</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">#</span> combinedInts</span>
<span id="cb33-2">lower <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=:</span> combinedInts <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">-.</span> higher</span>
<span id="cb33-3"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Higher'</span> outArray higher</span>
<span id="cb33-4"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'Lower'</span> outArray lower</span></code></pre></div></div>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb34" style="background: #f1f3f5;"><pre class="sourceCode j code-with-copy"><code class="sourceCode j"><span id="cb34-1">Higher<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>]<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">31</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">33</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">44</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">55</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">66</span></span>
<span id="cb34-2">Lower<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>]<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">7</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">8</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">10</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span></span></code></pre></div></div>
<p>We now have two lists: One containing all of the integers above average and another containing the rest.</p>
</section>
</section>
<section id="in-summary" class="level3">
<h3 class="anchored" data-anchor-id="in-summary">In Summary</h3>
<p>It is difficult to understand what I found to be so satisfying about learning and using J:</p>
<ul>
<li>I think that partly it was the challenge - a challenge to learn a language that was very different to other languages that I had used.</li>
<li>I found the clarity of documentation, at <a href="https://www.jsoftware.com">www.jsoftware.com</a>, to be of a level that I had only previously found in old Unix, Plan 9 or Inferno documentation.</li>
<li>It felt like the features of the language were necessary and sufficient to allow a particular problem to be solved.</li>
<li>I can begin to see how having a terse language can help an experienced reader to visualise a complex algorithm without having to page around in source code.</li>
<li>There didn’t seem to be a big overlap between the roles of the system verbs. It didn’t feel like there was supposed to be more than one way to do something (I’m reminded of Perl here).</li>
<li>J has a very mathematical, and precise, feel to it.</li>
<li>Using J and its ecosystem has helped to reinforce my belief that newer is certainly not always better.</li>
</ul>
<p>Sadly, it also feels as though J might not be around for ever, and that would be a shame.</p>


</section>

 ]]></description>
  <category>J</category>
  <category>APL</category>
  <guid>https://www.oldgang.net/notebooks/posts/the_lure_of_j/the_lure_of_j.html</guid>
  <pubDate>Mon, 08 May 2023 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Mazda 3 Price Data - Tabulation</title>
  <dc:creator>John Bates</dc:creator>
  <link>https://www.oldgang.net/notebooks/posts/car_prices_mazda3/04.tabulation/tabulation.html</link>
  <description><![CDATA[ 




<p>This notebook looks at methods of tabulating the data in the car price data dataset (see <a href="../../../../notebooks/posts/car_prices_mazda3/01.preparation/preparation.html">Mazda 3 Price Data - Preparation</a>). The aim is to look at ways of presenting simple one or two dimensional summary tables with as little code as possible. All of the manipulation of data will be done using functions from the <code>dplyr</code> or <code>tidyr</code> packages, both of which are part of the <code>tidyverse</code> umbrella package.</p>
<p>I feel sure that there should be a simple R package for creating simple tables, with aggregated values, from a dataframe. But, at the time of writing, I could not find one that was simple or mature enough to persuade me to use it. Hopefully that will change soon.</p>
<p>In the meantime, I demonstrate one technique that uses the <code>tidyverse</code> packages to build a two-dimensional table that handles the calculation and display of aggregated data and includes the correct calculation of aggregate values for row, column and grand totals.</p>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Note
</div>
</div>
<div class="callout-body-container callout-body">
<p>In this notebook where we want to talk about the rows or columns of a displayed table we will use the terms row dimension and column dimension. Using dimension, rather than variable or column, will help make it clear that we are talking about the horizontal or vertical dimension of a displayed table rather than a property of a dataframe or underlying model.</p>
</div>
</div>
<p>The technique for creating a table is to build a dataframe that holds the entire table structure and then to display it using the appropriate mechanism. Output in this notebook is by means of the <code>knitr::kable</code> function.</p>
<p>We start by reading in the cars tibble that we created and saved.</p>
<div class="cell" data-hash="tabulation_cache/html/unnamed-chunk-1_7a891882a4e250b4a687ca03b7c6646f">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb1-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(tidyverse)</span>
<span id="cb1-2">cars <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">readRDS</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"../01.preparation/mazda3.rds"</span>)</span></code></pre></div></div>
</div>
<p>For the purposes of this notebook we ensure that we have a value of monthly depreciation for all vehicles by setting it to 250 (a high value) for all vehicles for which we do not already have a value.</p>
<div class="cell" data-hash="tabulation_cache/html/unnamed-chunk-2_629627a5095dd49522ac88ec18a8ee90">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb2-1">cars <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span></span>
<span id="cb2-2">  cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb2-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">depreciation_per_month =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ifelse</span>(new_used <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"New"</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">250</span>, depreciation_per_month))</span></code></pre></div></div>
</div>
<p>Suppose that we would like to create a simple ordered, one-dimensional listing that shows the count and median monthly depreciation for each combination of variant, and engine.</p>
<p>We choose the columns that we are interested in using the <code>select</code> function.</p>
<p>Then we use <code>group_by</code> followed by <code>summarise</code> to reduce the data. Our output will contain a row for each combination of the columns named in the call to <code>group_by</code> - these columns will be shown in the output.</p>
<p>In addition, any values that we define in the call to <code>summarize</code> will also show up in the output in columns in the listing immediately following the group-by columns. Their values will be calculated for each of the groups - each of the combinations of the group-by columns. The aggregating functions can make use of any of the columns that we have selected from the dataframe. The special function <code>n()</code> returns the current group size.</p>
<p>The <code>arrange</code> function orders the output into ascending or descending order based on the values of one or more columns.</p>
<div class="cell" data-hash="tabulation_cache/html/unnamed-chunk-3_98e0de0348942f753652a10369e1c874">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb3-1">cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb3-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(depreciation_per_month, variant, engine) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb3-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(variant, engine) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb3-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">n=</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">n</span>(), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">median_dpm =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(depreciation_per_month)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb3-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">arrange</span>(median_dpm) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb3-6">  knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">variant</th>
<th style="text-align: left;">engine</th>
<th style="text-align: right;">n</th>
<th style="text-align: right;">median_dpm</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">SE-L</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">41</td>
<td style="text-align: right;">161</td>
</tr>
<tr class="even">
<td style="text-align: left;">SE-L Lux</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">51</td>
<td style="text-align: right;">188</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Sport Lux</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">114</td>
<td style="text-align: right;">197</td>
</tr>
<tr class="even">
<td style="text-align: left;">GT Sport</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">53</td>
<td style="text-align: right;">214</td>
</tr>
<tr class="odd">
<td style="text-align: left;">SE-L Lux</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">6</td>
<td style="text-align: right;">222</td>
</tr>
<tr class="even">
<td style="text-align: left;">GT Sport</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">28</td>
<td style="text-align: right;">233</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Sport Lux</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">29</td>
<td style="text-align: right;">239</td>
</tr>
<tr class="even">
<td style="text-align: left;">GT Sport Tech</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">15</td>
<td style="text-align: right;">249</td>
</tr>
<tr class="odd">
<td style="text-align: left;">GT Sport Tech</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">42</td>
<td style="text-align: right;">250</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>If we want to create a two-dimensional table we need to use the <code>pivot_wider</code> function to declare which column of the dataframe will appear at the table column dimension and what values will be displayed in the cells of the table.</p>
<div class="cell" data-hash="tabulation_cache/html/unnamed-chunk-4_d3a7c388737f2ab954e971785e07b3d3">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb4-1">cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb4-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(variant, engine, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm=</span>depreciation_per_month) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb4-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(variant, engine) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb4-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>( <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(dpm)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb4-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pivot_wider</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">names_from=</span>engine, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_from=</span>dpm) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb4-6">  knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">variant</th>
<th style="text-align: right;">e-Skyactiv G</th>
<th style="text-align: right;">e-Skyactiv X</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">SE-L</td>
<td style="text-align: right;">161</td>
<td style="text-align: right;">NA</td>
</tr>
<tr class="even">
<td style="text-align: left;">SE-L Lux</td>
<td style="text-align: right;">188</td>
<td style="text-align: right;">222</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Sport Lux</td>
<td style="text-align: right;">197</td>
<td style="text-align: right;">239</td>
</tr>
<tr class="even">
<td style="text-align: left;">GT Sport</td>
<td style="text-align: right;">214</td>
<td style="text-align: right;">233</td>
</tr>
<tr class="odd">
<td style="text-align: left;">GT Sport Tech</td>
<td style="text-align: right;">250</td>
<td style="text-align: right;">249</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>We have seen that without using <code>pivot_wider</code> we get a listing output that includes our two group-by columns (variant and engine). We use the <code>names_from</code> argument to <code>pivot_wider</code> to declare the dataframe column that will provide the values for the column dimension of our table. We use the <code>values_from</code> argument to <code>pivot_wider</code> to declare the dataframe column whose values will be displayed in the cells of the table. The remaining group-by column will provide the values for the row dimension of the table.</p>
<div class="cell" data-hash="tabulation_cache/html/unnamed-chunk-5_66e4d5e8cfd5b5e986c743166db46b1d">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb5-1">cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb5-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(variant, engine, new_used, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm=</span>depreciation_per_month) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb5-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(variant, engine, new_used) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb5-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>( <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(dpm)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb5-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pivot_wider</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">names_from=</span>engine, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_from=</span>dpm) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb5-6">  knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">variant</th>
<th style="text-align: left;">new_used</th>
<th style="text-align: right;">e-Skyactiv G</th>
<th style="text-align: right;">e-Skyactiv X</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">SE-L</td>
<td style="text-align: left;">Used</td>
<td style="text-align: right;">161</td>
<td style="text-align: right;">NA</td>
</tr>
<tr class="even">
<td style="text-align: left;">SE-L Lux</td>
<td style="text-align: left;">Used</td>
<td style="text-align: right;">187</td>
<td style="text-align: right;">213</td>
</tr>
<tr class="odd">
<td style="text-align: left;">SE-L Lux</td>
<td style="text-align: left;">New</td>
<td style="text-align: right;">250</td>
<td style="text-align: right;">250</td>
</tr>
<tr class="even">
<td style="text-align: left;">Sport Lux</td>
<td style="text-align: left;">Used</td>
<td style="text-align: right;">194</td>
<td style="text-align: right;">229</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Sport Lux</td>
<td style="text-align: left;">New</td>
<td style="text-align: right;">250</td>
<td style="text-align: right;">250</td>
</tr>
<tr class="even">
<td style="text-align: left;">GT Sport</td>
<td style="text-align: left;">Used</td>
<td style="text-align: right;">207</td>
<td style="text-align: right;">233</td>
</tr>
<tr class="odd">
<td style="text-align: left;">GT Sport</td>
<td style="text-align: left;">New</td>
<td style="text-align: right;">250</td>
<td style="text-align: right;">250</td>
</tr>
<tr class="even">
<td style="text-align: left;">GT Sport Tech</td>
<td style="text-align: left;">Used</td>
<td style="text-align: right;">223</td>
<td style="text-align: right;">249</td>
</tr>
<tr class="odd">
<td style="text-align: left;">GT Sport Tech</td>
<td style="text-align: left;">New</td>
<td style="text-align: right;">250</td>
<td style="text-align: right;">NA</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>In the above table we have reduced the dataframe to a variant value on the rows, an engine name on the columns and the median monthly depreciation values for each combination of row value and column value in each of the cells.</p>
<p>In general, the procedure is to group the data by the two variables that are to make up the row and column values. Then, summarise the group by the statistic that you want to display in the table cells.</p>
<p>Specify the variable that you want to use to supply the column values of the table in the <code>names_from</code> argument to <code>pivot_wider</code> and the summary statistic that you want to use to supply the cell values of the table in the <code>values_from</code> argument to <code>pivot_wider</code>.</p>
<p>By default, missing values will be shown in the table as <code>NA</code>. If you want them to be replaced by an alternative value then the <code>values_fill</code> argument can supply the replacement.</p>
<p>If you need to represent more than two dimensions in the table you can combine two into the columns by providing them both to <code>names_from</code> but this only really works if the number of values are relatively small and the length of the values of the columns are also relatively short.</p>
<div class="cell" data-hash="tabulation_cache/html/unnamed-chunk-6_b5e550dfff2ded04b15497dab2f4dd79">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb6-1">cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb6-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(variant, engine, new_used, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm=</span>depreciation_per_month) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb6-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(variant, engine, new_used) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb6-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">n =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">n</span>()) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb6-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pivot_wider</span>(</span>
<span id="cb6-6">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">names_from=</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(engine,new_used), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_from=</span>n, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_fill=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span></span>
<span id="cb6-7">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb6-8">  knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<colgroup>
<col style="width: 16%">
<col style="width: 21%">
<col style="width: 20%">
<col style="width: 21%">
<col style="width: 20%">
</colgroup>
<thead>
<tr class="header">
<th style="text-align: left;">variant</th>
<th style="text-align: right;">e-Skyactiv G_Used</th>
<th style="text-align: right;">e-Skyactiv G_New</th>
<th style="text-align: right;">e-Skyactiv X_Used</th>
<th style="text-align: right;">e-Skyactiv X_New</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">SE-L</td>
<td style="text-align: right;">41</td>
<td style="text-align: right;">0</td>
<td style="text-align: right;">0</td>
<td style="text-align: right;">0</td>
</tr>
<tr class="even">
<td style="text-align: left;">SE-L Lux</td>
<td style="text-align: right;">50</td>
<td style="text-align: right;">1</td>
<td style="text-align: right;">5</td>
<td style="text-align: right;">1</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Sport Lux</td>
<td style="text-align: right;">109</td>
<td style="text-align: right;">5</td>
<td style="text-align: right;">26</td>
<td style="text-align: right;">3</td>
</tr>
<tr class="even">
<td style="text-align: left;">GT Sport</td>
<td style="text-align: right;">50</td>
<td style="text-align: right;">3</td>
<td style="text-align: right;">27</td>
<td style="text-align: right;">1</td>
</tr>
<tr class="odd">
<td style="text-align: left;">GT Sport Tech</td>
<td style="text-align: right;">39</td>
<td style="text-align: right;">3</td>
<td style="text-align: right;">15</td>
<td style="text-align: right;">0</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>A better solution is to use the longer variables as table rows and use the smallest and shortest variable as the table columns.</p>
<div class="cell" data-hash="tabulation_cache/html/unnamed-chunk-7_376a2d140a7fa48decd6c09c61f175b4">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb7-1">cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb7-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(variant, engine, new_used, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm=</span>depreciation_per_month) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb7-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(variant, engine, new_used) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb7-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">n =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">n</span>()) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb7-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pivot_wider</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">names_from=</span>new_used, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_from=</span>n, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_fill=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb7-6">  knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">variant</th>
<th style="text-align: left;">engine</th>
<th style="text-align: right;">Used</th>
<th style="text-align: right;">New</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">SE-L</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">41</td>
<td style="text-align: right;">0</td>
</tr>
<tr class="even">
<td style="text-align: left;">SE-L Lux</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">50</td>
<td style="text-align: right;">1</td>
</tr>
<tr class="odd">
<td style="text-align: left;">SE-L Lux</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">5</td>
<td style="text-align: right;">1</td>
</tr>
<tr class="even">
<td style="text-align: left;">Sport Lux</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">109</td>
<td style="text-align: right;">5</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Sport Lux</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">26</td>
<td style="text-align: right;">3</td>
</tr>
<tr class="even">
<td style="text-align: left;">GT Sport</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">50</td>
<td style="text-align: right;">3</td>
</tr>
<tr class="odd">
<td style="text-align: left;">GT Sport</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">27</td>
<td style="text-align: right;">1</td>
</tr>
<tr class="even">
<td style="text-align: left;">GT Sport Tech</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">39</td>
<td style="text-align: right;">3</td>
</tr>
<tr class="odd">
<td style="text-align: left;">GT Sport Tech</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">15</td>
<td style="text-align: right;">0</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>If none of the arrangements looks good then revert to using the one-dimensional listing format with one or more summarised values that we started this notebook with.</p>
<p>A simple form of table caption can be provided in the call to <code>knitr::kable</code>.</p>
<div class="cell" data-hash="tabulation_cache/html/unnamed-chunk-8_8bd3913fdd5831a69c6fe8fe2f2f4756">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb8-1">cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb8-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(variant, engine, new_used, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm=</span>depreciation_per_month) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb8-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(engine, new_used) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb8-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">n =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">n</span>()) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb8-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pivot_wider</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">names_from=</span>new_used, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_from=</span>n, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_fill=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb8-6">  knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">caption=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"A Count of New/Used by Engine"</span>)</span></code></pre></div></div>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<caption>A Count of New/Used by Engine</caption>
<thead>
<tr class="header">
<th style="text-align: left;">engine</th>
<th style="text-align: right;">Used</th>
<th style="text-align: right;">New</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">289</td>
<td style="text-align: right;">12</td>
</tr>
<tr class="even">
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">73</td>
<td style="text-align: right;">5</td>
</tr>
</tbody>
</table>
</div>
</div>
<section id="row-totals---counts" class="level3">
<h3 class="anchored" data-anchor-id="row-totals---counts">Row Totals - Counts</h3>
<p>The mechanism can be extended to include row totals. The technique is to create a dataframe for the body of the table and another dataframe for the rowtotal and then to combine them with <code>bind_rows</code>.</p>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Note
</div>
</div>
<div class="callout-body-container callout-body">
<p>The terminology of row-totals and column-totals can be a little confusing. In this notebook a row-total is a row that appears beneath the main body of a table and a column-total is a column that appears to the right of the main body of a table.</p>
</div>
</div>
<div class="cell" data-hash="tabulation_cache/html/unnamed-chunk-9_e62437dbe60065cd01abe03f54f5aad4">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb9-1">body <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb9-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(engine, new_used) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb9-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(engine, new_used) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb9-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">n =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">n</span>()) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb9-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pivot_wider</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">names_from=</span>new_used, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_from=</span>n, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_fill=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>) </span>
<span id="cb9-6"></span>
<span id="cb9-7">rowtotals <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> body <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb9-8">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>() <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb9-9">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(</span>
<span id="cb9-10">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">across</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">where</span>(is.factor), <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Total"</span>),</span>
<span id="cb9-11">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">across</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">where</span>(is.numeric), sum)</span>
<span id="cb9-12">  ) </span>
<span id="cb9-13"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">bind_rows</span>(body, rowtotals) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb9-14">knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">engine</th>
<th style="text-align: right;">Used</th>
<th style="text-align: right;">New</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">289</td>
<td style="text-align: right;">12</td>
</tr>
<tr class="even">
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">73</td>
<td style="text-align: right;">5</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Total</td>
<td style="text-align: right;">362</td>
<td style="text-align: right;">17</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>This is fine for simple additive counts, but for aggregates we need something better.</p>
</section>
<section id="row-totals---aggregates" class="level3">
<h3 class="anchored" data-anchor-id="row-totals---aggregates">Row Totals - Aggregates</h3>
<p>The problem with tables containing aggregates is that the aggregate of a column of aggregates is not the same as the aggregate you would obtain had you not previously grouped on the rows. An easy way to see this is to imagine dividing a collection of values up into two unequally sized groups. You can calculate the mean of each group but the mean of the whole collection is not equal in value to the mean of the two group means (it would be if the two groups were equally sized).</p>
<p>To calculate aggregates correctly for row totals we need to start with the cars dataframe and perform a different grouping for each kind of aggregate. Instead of grouping and summarising the body dataframe as we did above, we obtain row totals by grouping the cars dataframe across the table columns. This allows us to calculate an aggregate value for each group (table column) and our rowtotal is constructed as a single row dataframe that contains an aggregate value in each column and a blank value or text label in any column for which no aggregate can be calculated. We populate these blank or label columns using the <code>mutate</code> function.</p>
<div class="cell" data-hash="tabulation_cache/html/unnamed-chunk-10_81e5eaf4c568c3393920f24f2522d463">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb10-1">body <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb10-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(engine, new_used, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm=</span>depreciation_per_month) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb10-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(engine, new_used) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb10-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(dpm, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">na.rm=</span>T)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb10-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pivot_wider</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">names_from=</span>new_used, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_from=</span>dpm, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_fill=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>) </span>
<span id="cb10-6"></span>
<span id="cb10-7">rowtotals <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb10-8">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(new_used, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm=</span>depreciation_per_month) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb10-9">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(new_used) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb10-10">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(dpm, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">na.rm=</span>T)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb10-11">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pivot_wider</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">names_from=</span>new_used, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_from=</span>dpm, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_fill=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb10-12">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">engine =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Median"</span>)</span>
<span id="cb10-13"></span>
<span id="cb10-14"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">bind_rows</span>(body, rowtotals) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb10-15">knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">engine</th>
<th style="text-align: right;">Used</th>
<th style="text-align: right;">New</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">197</td>
<td style="text-align: right;">250</td>
</tr>
<tr class="even">
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">233</td>
<td style="text-align: right;">250</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Median</td>
<td style="text-align: right;">202</td>
<td style="text-align: right;">250</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>You will notice that the aggregate value for the Used column is no longer the sum of the numbers above it - it is not even the mean or median of them. It is the median of the values of the dataframe Used column but not grouped by engine.</p>
</section>
<section id="row-column-and-grand-totals---aggregates" class="level3">
<h3 class="anchored" data-anchor-id="row-column-and-grand-totals---aggregates">Row, Column and Grand Totals - Aggregates</h3>
<p>To create a table with the full set of totals we reduce (group-by and summarise) the cars dataframe to build each of the totals, so that we handle aggregates correctly, and then we stitch them together into a table.</p>
<div class="cell" data-hash="tabulation_cache/html/unnamed-chunk-11_f13784d25b7e809428aac0050b13b4c6">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb11-1">body <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb11-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(engine, new_used, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm=</span>depreciation_per_month) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb11-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(engine, new_used) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb11-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(dpm, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">na.rm=</span>T)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb11-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pivot_wider</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">names_from=</span>new_used, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_from=</span>dpm, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_fill=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>) </span>
<span id="cb11-6"></span>
<span id="cb11-7">rowtotals <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb11-8">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(new_used, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm=</span>depreciation_per_month) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb11-9">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(new_used) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb11-10">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(dpm, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">na.rm=</span>T)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb11-11">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pivot_wider</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">names_from=</span>new_used, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_from=</span>dpm, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_fill=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb11-12">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">engine =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Median"</span>)</span>
<span id="cb11-13"></span>
<span id="cb11-14">coltotals <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb11-15">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(engine, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm=</span>depreciation_per_month) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb11-16">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(engine) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb11-17">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">Median =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(dpm, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">na.rm=</span>T))</span>
<span id="cb11-18"></span>
<span id="cb11-19">grandtotal <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb11-20">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm=</span>depreciation_per_month) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb11-21">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">engine=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Median"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">Median =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(dpm, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">na.rm=</span>T)) </span>
<span id="cb11-22"></span>
<span id="cb11-23">all <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">inner_join</span>(</span>
<span id="cb11-24">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">bind_rows</span>(body, rowtotals),</span>
<span id="cb11-25">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">bind_rows</span>(coltotals, grandtotal)</span>
<span id="cb11-26">)</span>
<span id="cb11-27">knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(all, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">engine</th>
<th style="text-align: right;">Used</th>
<th style="text-align: right;">New</th>
<th style="text-align: right;">Median</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">197</td>
<td style="text-align: right;">250</td>
<td style="text-align: right;">197</td>
</tr>
<tr class="even">
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">233</td>
<td style="text-align: right;">250</td>
<td style="text-align: right;">238</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Median</td>
<td style="text-align: right;">202</td>
<td style="text-align: right;">250</td>
<td style="text-align: right;">202</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>This seems like quite a lot of work for a 3-row by 4-column table but it is quite flexible. If you can see from the above code fragment how the table is constructed there is no need to read the next section which simply shows a breakdown of each stage of the table construction.</p>
</section>
<section id="assembly-of-the-complete-table---bit-by-bit" class="level3">
<h3 class="anchored" data-anchor-id="assembly-of-the-complete-table---bit-by-bit">Assembly of the Complete Table - Bit by Bit</h3>
<p>We begin by creating the body of the table.</p>
<div class="cell" data-hash="tabulation_cache/html/unnamed-chunk-12_65820588c5321cdd7601c630104c5e28">
<details class="code-fold">
<summary>Show the code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb12-1">body <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb12-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(engine, new_used, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm=</span>depreciation_per_month) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb12-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(engine, new_used) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb12-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(dpm, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">na.rm=</span>T)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb12-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pivot_wider</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">names_from=</span>new_used, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_from=</span>dpm, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_fill=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>) </span>
<span id="cb12-6">knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(body, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
</details>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">engine</th>
<th style="text-align: right;">Used</th>
<th style="text-align: right;">New</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">197</td>
<td style="text-align: right;">250</td>
</tr>
<tr class="even">
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">233</td>
<td style="text-align: right;">250</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>Then we create the row totals as a single row dataframe with a value for each table column. It does not matter that the engine column appears as the last column in the dataframe.</p>
<div class="cell" data-hash="tabulation_cache/html/unnamed-chunk-13_3397b5d89ccbe7cd0e2007a9d076d7d4">
<details class="code-fold">
<summary>Show the code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb13-1">rowtotals <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb13-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(new_used, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm=</span>depreciation_per_month) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb13-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(new_used) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb13-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(dpm, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">na.rm=</span>T)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb13-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pivot_wider</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">names_from=</span>new_used, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_from=</span>dpm, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_fill=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb13-6">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">engine =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Median"</span>)</span>
<span id="cb13-7">knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(rowtotals, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
</details>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: right;">Used</th>
<th style="text-align: right;">New</th>
<th style="text-align: left;">engine</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: right;">202</td>
<td style="text-align: right;">250</td>
<td style="text-align: left;">Median</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>We create the column totals as a dataframe with a row for each row in the main body of the table. Each row contains a field (or fields) that allows us to find the table row with which to associate it, and a value to use as the column total.</p>
<div class="cell" data-hash="tabulation_cache/html/unnamed-chunk-14_b572f56114b22300d48f1657599570df">
<details class="code-fold">
<summary>Show the code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb14-1">coltotals <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb14-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(engine, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm=</span>depreciation_per_month) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb14-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(engine) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb14-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">Median =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(dpm, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">na.rm=</span>T))</span>
<span id="cb14-5">knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(coltotals, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
</details>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">engine</th>
<th style="text-align: right;">Median</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">197</td>
</tr>
<tr class="even">
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">238</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>The grand total is a dataframe with a single row and a column that will link it to the rowtotal row of the table and a value to use as the grand total.</p>
<div class="cell" data-hash="tabulation_cache/html/unnamed-chunk-15_d72442f847e4d7fd78287b94fe868fcc">
<details class="code-fold">
<summary>Show the code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb15" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb15-1">grandtotal <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb15-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm=</span>depreciation_per_month) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb15-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">engine=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Median"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">Median =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(dpm, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">na.rm=</span>T)) </span>
<span id="cb15-4">knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(grandtotal, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
</details>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">engine</th>
<th style="text-align: right;">Median</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">Median</td>
<td style="text-align: right;">202</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>We bind the body and the rowtotals together into a single dataframe. The rowtotals appear as the final row of the dataframe. The values in the engine column are going to be used to position the column totals and the grand total correctly later.</p>
<div class="cell" data-hash="tabulation_cache/html/unnamed-chunk-16_0c7af2323e9f2f1e6413aa3e4c83f595">
<details class="code-fold">
<summary>Show the code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb16" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb16-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">bind_rows</span>(body, rowtotals) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb16-2">knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
</details>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">engine</th>
<th style="text-align: right;">Used</th>
<th style="text-align: right;">New</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">197</td>
<td style="text-align: right;">250</td>
</tr>
<tr class="even">
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">233</td>
<td style="text-align: right;">250</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Median</td>
<td style="text-align: right;">202</td>
<td style="text-align: right;">250</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>So we now have the main body of the table and the row totals in a single dataframe. Next we need to create a similar dataframe containing the column totals and the grand total.</p>
<p>We bind the coltotals and the grandtotal together into a single dataframe.</p>
<div class="cell" data-hash="tabulation_cache/html/unnamed-chunk-17_a837ffc366edbc85cc5bca763b80046c">
<details class="code-fold">
<summary>Show the code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb17" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb17-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">bind_rows</span>(coltotals, grandtotal) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb17-2">knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
</details>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">engine</th>
<th style="text-align: right;">Median</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">197</td>
</tr>
<tr class="even">
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">238</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Median</td>
<td style="text-align: right;">202</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>Finally, we glue the two dataframes together by joining them on their common <code>engine</code> column. This is the column that contains values of the row dimension of the table.</p>
<p>The join ensures that the columns from the body and rowtotals appear before the columns from the coltotals and grandtotal. So the effect that we get is that the Median column appears as the last table column.</p>
<div class="cell" data-hash="tabulation_cache/html/unnamed-chunk-18_4b109191249bc3a9856e7fd7ab117288">
<details class="code-fold">
<summary>Show the code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb18" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb18-1">all <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">inner_join</span>(</span>
<span id="cb18-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">bind_rows</span>(body, rowtotals),</span>
<span id="cb18-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">bind_rows</span>(coltotals, grandtotal)</span>
<span id="cb18-4">)</span>
<span id="cb18-5">knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(all, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
</details>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">engine</th>
<th style="text-align: right;">Used</th>
<th style="text-align: right;">New</th>
<th style="text-align: right;">Median</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">197</td>
<td style="text-align: right;">250</td>
<td style="text-align: right;">197</td>
</tr>
<tr class="even">
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">233</td>
<td style="text-align: right;">250</td>
<td style="text-align: right;">238</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Median</td>
<td style="text-align: right;">202</td>
<td style="text-align: right;">250</td>
<td style="text-align: right;">202</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>And that is our complete table.</p>
<p>The deconstruction makes is sound like more work than it really is.</p>


</section>

 ]]></description>
  <category>R</category>
  <category>Car Price</category>
  <category>Mazda 3</category>
  <guid>https://www.oldgang.net/notebooks/posts/car_prices_mazda3/04.tabulation/tabulation.html</guid>
  <pubDate>Wed, 03 May 2023 02:00:00 GMT</pubDate>
</item>
<item>
  <title>Mazda 3 Price Data - Modelling</title>
  <dc:creator>John Bates</dc:creator>
  <link>https://www.oldgang.net/notebooks/posts/car_prices_mazda3/03.modelling/modelling.html</link>
  <description><![CDATA[ 




<p>Given the cleaned dataset that we created in the companion notebook <a href="../../../../notebooks/posts/car_prices_mazda3/01.preparation/preparation.html">Mazda 3 Price Data - Preparation</a> we now want to attempt to obtain some numerical estimates of how different variables affect the monthly car price depreciation. As in the previous notebook we will be using the <code>tidyverse</code> packages.</p>
<p>We start by reading in the cars tibble that we created and saved.</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-1_876c1dd757a0fbfc7932107391a0a0cc">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb1-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(tidyverse)</span>
<span id="cb1-2">cars <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">readRDS</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"../01.preparation/mazda3.rds"</span>)</span></code></pre></div></div>
</div>
<p>We restrict its content to used “Used” cars. And we restrict its content to cars for which we have a value for depreciation_per_month.</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-2_3e3ccd8a3393bf5f68469a622801d40f">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb2-1">cars <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb2-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(new_used <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Used"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb2-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">is.na</span>(depreciation_per_month))</span></code></pre></div></div>
</div>
<p>We ended the visualisation notebook with a table of monthly median depreciation values for each combination of variant and engine.</p>
<p>These are ordered in ascending order of the median depreciation per month.</p>
<div class="cell" data-hash="modelling_cache/html/fig-group-median_caebecb9e67a48b8e2eb5fe45d1d65d8">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb3-1">cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb3-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(depreciation_per_month, variant, engine) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb3-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(variant, engine) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb3-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">n=</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">n</span>(), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">median_dpm =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(depreciation_per_month)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb3-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">arrange</span>(median_dpm) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb3-6">  knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
<div id="fig-group-median" class="cell-output-display quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-group-median-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">variant</th>
<th style="text-align: left;">engine</th>
<th style="text-align: right;">n</th>
<th style="text-align: right;">median_dpm</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">SE-L</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">41</td>
<td style="text-align: right;">161</td>
</tr>
<tr class="even">
<td style="text-align: left;">SE-L Lux</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">50</td>
<td style="text-align: right;">187</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Sport Lux</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">109</td>
<td style="text-align: right;">194</td>
</tr>
<tr class="even">
<td style="text-align: left;">GT Sport</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">50</td>
<td style="text-align: right;">207</td>
</tr>
<tr class="odd">
<td style="text-align: left;">SE-L Lux</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">5</td>
<td style="text-align: right;">213</td>
</tr>
<tr class="even">
<td style="text-align: left;">GT Sport Tech</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">39</td>
<td style="text-align: right;">223</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Sport Lux</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">26</td>
<td style="text-align: right;">229</td>
</tr>
<tr class="even">
<td style="text-align: left;">GT Sport</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">27</td>
<td style="text-align: right;">233</td>
</tr>
<tr class="odd">
<td style="text-align: left;">GT Sport Tech</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">15</td>
<td style="text-align: right;">249</td>
</tr>
</tbody>
</table>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-group-median-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;1: Summarising by group median.
</figcaption>
</figure>
</div>
</div>
<p>The difference in depreciation between the SE-L Lux with the e-Skyactiv G engine and the top of the range GT Sport Tech with the e-Skyactiv X engine is about £88 per month.</p>
<p>One method available to us is to perform a linear regression of our independent variables (variant, engine, age_in_months and miles_per_month) on our dependent variable (depreciation_per_month).</p>
<p>There are several assumptions made when using linear regression:</p>
<ol type="1">
<li><strong>The independent variables are truly independent of each other</strong>: This is a reasonable assumption here, especially after we converted depreciation to depreciation_per_month and miles to miles_per_month thereby removing a dependency on age_in_months.</li>
<li><strong>There are no outliers</strong>: We will ensure that below.</li>
<li><strong>The variables are normally distributed</strong>: This one is a little more tricky. Some are, some not so much.</li>
<li><strong>There is a linear relationship between the independent variables and the dependent variable</strong>: An assumption that we will make based on the scatter-plots of the previous notebook.</li>
</ol>
<p>A <code>pairs.panels</code> plot from the <code>psych</code> library confirms that the correlations between the independent variables are low.</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-4_378a68f06a96c7a7483d0f36a05b10f5">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb4-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"psych"</span>)</span>
<span id="cb4-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pairs.panels</span>(</span>
<span id="cb4-3">  cars[<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>( <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"variant"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"engine"</span>,<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"age_in_months"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"miles_per_month"</span>)],</span>
<span id="cb4-4">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">cor=</span>T</span>
<span id="cb4-5">)</span></code></pre></div></div>
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://www.oldgang.net/notebooks/posts/car_prices_mazda3/03.modelling/modelling_files/figure-html/unnamed-chunk-4-1.png" class="img-fluid figure-img" width="672"></p>
</figure>
</div>
</div>
</div>
<p>We should also consider removing outliers from our analysis. The outliers are the observations that lie beyond the extremes of the whiskers in a box and whiskers plot. That is, those observations that are more than 1.5 times the interquartile range above or below the 75% and 25% quartiles.</p>
<p>We can see the outliers on the boxplot.</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-5_19781624f026b9f76e592f8469b97602">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb5-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(</span>
<span id="cb5-2">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> cars,</span>
<span id="cb5-3">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">mapping =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> depreciation_per_month)</span>
<span id="cb5-4">) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_boxplot</span>() </span></code></pre></div></div>
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://www.oldgang.net/notebooks/posts/car_prices_mazda3/03.modelling/modelling_files/figure-html/unnamed-chunk-5-1.png" class="img-fluid figure-img" width="672"></p>
</figure>
</div>
</div>
</div>
<p>These can be captured and removed by calculating the interquartile range and the 25% and 75% quantiles.</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-6_ebd2ba4a37a6e8a07f8b0296d4848813">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb6-1">iqr <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">IQR</span>(cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>depreciation_per_month)</span>
<span id="cb6-2"></span>
<span id="cb6-3">q25 <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">quantile</span>(cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>depreciation_per_month, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.25</span>)</span>
<span id="cb6-4">q75 <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">quantile</span>(cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>depreciation_per_month, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.75</span>)</span>
<span id="cb6-5">lower <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> q25 <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.5</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>iqr</span>
<span id="cb6-6">upper <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> q75 <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.5</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>iqr</span>
<span id="cb6-7"></span>
<span id="cb6-8">outliers <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb6-9">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(</span>
<span id="cb6-10">      depreciation_per_month <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> upper</span>
<span id="cb6-11">    <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> depreciation_per_month <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> lower</span>
<span id="cb6-12">  )</span></code></pre></div></div>
</div>
<p>We can examine the outliers by variant and engine and then calculate their median depreciation_per_month (dpm), depreciation (d) and age_in_months (a).</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-7_51443721e22349d56d34b3a5226a264c">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb7-1">outliers <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb7-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(</span>
<span id="cb7-3">    depreciation_per_month, variant, engine,</span>
<span id="cb7-4">    depreciation, age_in_months</span>
<span id="cb7-5">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb7-6">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(variant, engine) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb7-7">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">n=</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">n</span>(),</span>
<span id="cb7-8">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(depreciation_per_month, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">na.rm=</span>T),</span>
<span id="cb7-9">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">d=</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(depreciation, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">na.rm=</span>T),</span>
<span id="cb7-10">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">a=</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(age_in_months, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">na.rm=</span>T)</span>
<span id="cb7-11">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb7-12">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">arrange</span>(dpm) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb7-13">  knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">variant</th>
<th style="text-align: left;">engine</th>
<th style="text-align: right;">n</th>
<th style="text-align: right;">dpm</th>
<th style="text-align: right;">d</th>
<th style="text-align: right;">a</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">GT Sport</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">1</td>
<td style="text-align: right;">321</td>
<td style="text-align: right;">10585</td>
<td style="text-align: right;">30</td>
</tr>
<tr class="even">
<td style="text-align: left;">SE-L Lux</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">1</td>
<td style="text-align: right;">326</td>
<td style="text-align: right;">4890</td>
<td style="text-align: right;">12</td>
</tr>
<tr class="odd">
<td style="text-align: left;">GT Sport Tech</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">14</td>
<td style="text-align: right;">350</td>
<td style="text-align: right;">6782</td>
<td style="text-align: right;">15</td>
</tr>
<tr class="even">
<td style="text-align: left;">GT Sport</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">5</td>
<td style="text-align: right;">393</td>
<td style="text-align: right;">5885</td>
<td style="text-align: right;">12</td>
</tr>
<tr class="odd">
<td style="text-align: left;">GT Sport Tech</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">2</td>
<td style="text-align: right;">446</td>
<td style="text-align: right;">4015</td>
<td style="text-align: right;">6</td>
</tr>
<tr class="even">
<td style="text-align: left;">Sport Lux</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">6</td>
<td style="text-align: right;">486</td>
<td style="text-align: right;">4021</td>
<td style="text-align: right;">9</td>
</tr>
<tr class="odd">
<td style="text-align: left;">SE-L</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">4</td>
<td style="text-align: right;">595</td>
<td style="text-align: right;">2035</td>
<td style="text-align: right;">0</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>We notice that the outliers look to be mainly from the very expensive combinations of variant and engine and so it may really be that they were highly depreciated vehicles. We could choose to leave these outliers in for the analysis and treat them as valid observations. But given that they are quite small in number and we will remove them.</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-8_498524a3db78110b301c74821f352e77">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb8-1">cars <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb8-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(</span>
<span id="cb8-3">      depreciation_per_month <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> upper</span>
<span id="cb8-4">    <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> depreciation_per_month <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> lower</span>
<span id="cb8-5">  )</span></code></pre></div></div>
</div>
<section id="linear-regression" class="level3">
<h3 class="anchored" data-anchor-id="linear-regression">Linear Regression</h3>
<p>To estimate the numeric effect of each of our independent variables on the value of the dependent <code>depreciation_per_month</code> variable we can perform a linear regression on the data.</p>
<p>A linear regression will fit a straight line through the data of the form:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0Adepreciation%5C_per%5C_month%20=%20%5Calpha%20+%20%5Cbeta_1%20*%20variant%20+%20%5Cbeta_2%20*%20engine%20...%0A"></p>
<p>We will be interested in the value of <img src="https://latex.codecogs.com/png.latex?%5Calpha">, and the accompanying <img src="https://latex.codecogs.com/png.latex?%5Cbeta"> values. The constant value <img src="https://latex.codecogs.com/png.latex?%5Calpha"> will give us the base monthly depreciation and the the <img src="https://latex.codecogs.com/png.latex?%5Cbeta">s will give us the amount by which the predicted monthly depreciation will be increased (or decreased) when a vehicle has the associated variant, or engine size. Or in the case of the continuous independent variables, how much the predicted monthly depreciation will increase with each month of age or mile of travel of the vehicle.</p>
<p>To handle the independent variables that are factors, the model will employ <em>dummy coding</em> to convert each value of the factor into a numeric variable that takes on the value zero or one according as the observation takes on that value of the factor. When performing this conversion the first level of the factor is left out as it represents the situation when all of the other dummy coded factor values for that factor take on the value zero. This will be a little clearer when we look at the results of the regression.</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-9_9b27231c8fd8597c440ca9cadae612c4">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb9-1">model.lm <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">lm</span>(</span>
<span id="cb9-2">  depreciation_per_month <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span></span>
<span id="cb9-3">    variant<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>engine<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>age_in_months<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>miles_per_month,</span>
<span id="cb9-4">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data=</span>cars</span>
<span id="cb9-5">)</span>
<span id="cb9-6"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summary</span>(model.lm)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>
Call:
lm(formula = depreciation_per_month ~ variant + engine + age_in_months + 
    miles_per_month, data = cars)

Residuals:
    Min      1Q  Median      3Q     Max 
-81.155 -11.602  -0.778  10.409 126.978 

Coefficients:
                       Estimate Std. Error t value Pr(&gt;|t|)    
(Intercept)          214.894125   7.507069  28.626  &lt; 2e-16 ***
variantSE-L Lux       -2.849454   5.030114  -0.566    0.571    
variantSport Lux       4.247137   4.369210   0.972    0.332    
variantGT Sport       19.093102   4.731430   4.035 6.82e-05 ***
variantGT Sport Tech  30.810686   5.099644   6.042 4.22e-09 ***
enginee-Skyactiv X    17.621812   3.129154   5.631 3.90e-08 ***
age_in_months         -1.565584   0.115622 -13.541  &lt; 2e-16 ***
miles_per_month        0.069169   0.004908  14.094  &lt; 2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 20.51 on 321 degrees of freedom
Multiple R-squared:  0.6885,    Adjusted R-squared:  0.6817 
F-statistic: 101.4 on 7 and 321 DF,  p-value: &lt; 2.2e-16</code></pre>
</div>
</div>
<p>The residuals in the output are an indication of how well (or badly) our model fits the observed values of depreciation_per_month. The first thing to notice is that the maximum and minimum values of the residuals are £126 and -£81 respectively. These are the worst cases. The 50% of observations that fall between the 1Q and 3Q values have residuals that range between -£11 and £11. That seems like a very comfortable range.</p>
<p>Before examining the fitted values we need to look at the goodness of fit. The <em>Adjusted R-squared</em> value of 0.6817 is good. This value gives us an indication of how well our model explains the variation in monthly depreciation - in this case approximately 68%.</p>
<p>We also see that the three stars against each of the independent variables (except for the SE-L Lux and the Sport Lux variants) tell us that it is extremely unlikely that they do not influence the value of our modelled dependent variable, depreciation_per_month.</p>
<p>The model doesn’t consider the SE-L Lux and Sport Lux variants to influence the depreciation_per_month in a significant way.</p>
<p>We can plot the residuals against the fitted values of the model:</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-10_5b49dbd347deb6b28c1f0e3539fc5c26">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb11-1">predicted <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">predict</span>(model.lm)</span>
<span id="cb11-2">residuals <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">residuals</span>(model.lm)</span>
<span id="cb11-3"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(</span>
<span id="cb11-4">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> cars,</span>
<span id="cb11-5">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> predicted, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> residuals)</span>
<span id="cb11-6">) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_point</span>()</span></code></pre></div></div>
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://www.oldgang.net/notebooks/posts/car_prices_mazda3/03.modelling/modelling_files/figure-html/unnamed-chunk-10-1.png" class="img-fluid figure-img" width="672"></p>
</figure>
</div>
</div>
</div>
<p>This seems like a reasonable spread, perhaps slightly wider towards the higher end of the predicted values but good enough. Given that we are happy with the fit of the model we can now look at the values of the various fitted coefficients.</p>
<p>Before we can do that though we need to understand how the non-numeric (nominal) dependent variables in our model are handled by the regression. We can see that:</p>
<ul>
<li>For our 5 level <code>variant</code> variable the model contains 4 parameters: variantSE-L Lux, variantSport Lux, variantGT Sport, variantGT Sport Tech.</li>
<li>For our 2 level <code>engine</code> variable the model contains a single parameter: enginee-Skyactiv X.</li>
<li>For our numeric <code>age_in_months</code> variable the model contains a single parameter: age_in_months.</li>
<li>For our numeric <code>miles_per_month</code> variable the model contains a single parameter: miles_per_month.</li>
</ul>
<p>The key thing to note is that each non-numeric variable (a factor in our dataset) is represented in the model by (n-1) parameters where n is the number of levels of the factor that represents the nominal variable. The regression ensures that the effect of the first of the factor levels is incorporated into the value of the estimated intercept. To see the effect of having one of the other factor levels in an observation we need to add its associated coefficient to the value of the intercept.</p>
<p>For example, to represent the <code>engine</code> factor our model has a parameter, enginee-Skyactiv X, with a coefficient of (roughly) 18. This tells us that, in general, a vehicle with the e-Skyactiv X engine will depreciate at £18 per month more than a vehicle with the e-Skyactiv G. If we plug the estimated intercept value and the rounded coefficients for the various model parameters into our model equation it looks like this:</p>
<pre><code>  depreciation_per_month = 215
    + 19 * variantGT Sport
    + 30 * variantGT Sport Tech
    + 18 * enginee-Skyactiv X
    - 1.56 * age_in_months
    + 0.07 * miles_per_month</code></pre>
<p>We have omitted the SE-L Lux and Sport Lux parameters from this model because the regression analysis determined that they have an insignificant effect on the monthly depreciation.</p>
<p>The intercept value of £215 can be considered to be the estimated monthly depreciation of a vehicle with variant=SE-L (or SE-L Lux or Sport Lux), engine=e-Skyactiv G, age_in_months=0 and miles_per_month=0.</p>
<p>Were we to replace our variant SE-L with a variant of GT Sport then we should expect our monthly depreciation to increase by £19. If we then further opted for the e-Skyactiv X engine we could add another £18 onto the estimated monthly depreciation.</p>
<p>Similarly for the numeric parameters, if we were to consider the same specification at 12 months old we would subtract 12 * £1.56 = £19 from the estimated monthly depreciation. And 1,000 mile per month of travel would add £70 onto the estimated monthly depreciation.</p>
<p>So the regression gives us a very understandable explanation of how much each of the independent variables affects the value of the monthly depreciation.</p>
</section>
<section id="regression-trees" class="level3">
<h3 class="anchored" data-anchor-id="regression-trees">Regression Trees</h3>
<p>An alternative to using linear regression to model our data is to use regression trees. A regression tree model is built by splitting the set of observations into two partitions in such a way as to maximise the reduction in variation between the observations that lie within each partition. This requires both a choice of feature to split on and then a value with which to partition the data on that feature.</p>
<p>For example, if the miles_per_month feature is chosen as the one that can maximise the reduction in variation, it might then be determined to partition the data into two sets: one whose miles_per_month value was &gt;1000 and one whose miles_per_month value was &lt;= 1000.</p>
<p>This gives us two nodes of a tree. Then the procedure is repeated on the data in each node, giving us four nodes, and so on until there is no significant reduction to be obtained by splitting further.</p>
<p>Once the tree has been constructed by repeating the above process we have:</p>
<ol type="1">
<li>A set of rules that result in a path to each of the leaf nodes.</li>
<li>A set of homogeneous data in each node from which a mean value of the dependent variable <code>depreciation_per_month</code> can be determined.</li>
</ol>
<p>For a new observation we can follow the set of rules until we arrive at a leaf node and then we can use the mean value of monthly depreciation of observations in that node as our estimate of the monthly depreciation of the new observation.</p>
<p>To build a regression tree we use the “rpart” package and its associated plotting package.</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-11_b1b2f15d4bbdaa532678eea0b4c14099">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb13-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(rpart)</span>
<span id="cb13-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(rpart.plot)</span></code></pre></div></div>
</div>
<p>We will build a regression tree model using the same variables that we used for the linear regression model.</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-12_fb1548fd1914f9b7fccb025a10089267">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb14-1">model.rt <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rpart</span>(</span>
<span id="cb14-2">  depreciation_per_month <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span></span>
<span id="cb14-3">    variant<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>engine<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>age_in_months<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>miles_per_month,</span>
<span id="cb14-4">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> cars</span>
<span id="cb14-5">)</span></code></pre></div></div>
</div>
<p>A good visual representation of the regression tree can be obtains by using <code>rpart.plot</code>.</p>
<div class="cell" data-hash="modelling_cache/html/fig-regression-tree_a5d6800b5e799b656a833988d1a4ab90">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb15" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb15-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rpart.plot</span>(model.rt)</span></code></pre></div></div>
<div class="cell-output-display">
<div id="fig-regression-tree" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-regression-tree-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<img src="https://www.oldgang.net/notebooks/posts/car_prices_mazda3/03.modelling/modelling_files/figure-html/fig-regression-tree-1.png" class="img-fluid figure-img" width="672">
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-regression-tree-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;2: Summarising by regression tree leaf node mean.
</figcaption>
</figure>
</div>
</div>
</div>
<p>We can see that the first variable that was split was <code>age_in_months</code> and that the resulting tree has five levels and terminates in 12 leaf nodes. The values within each node are the mean depreciation_per_month of the observations that fall into that node and the percentage of the observations that reach that point.</p>
<p>Because <code>age_in_months</code> was used first in the tree it is the single most important predictor of the monthly depreciation of a vehicle. The regression model divides the observations on <code>age_in_months &gt;= 33</code>, placing all observations for which this is true in the node on the left-hand-side of the split and all other observations in the node on the right-hand-side.</p>
<p>We can repeat this process right the way down the tree. If we consider the observations for which <code>age_in_months</code> is not greater than 33 (i.e.&nbsp;relatively new vehicles) then the next best predictor of monthly depreciation is <code>miles_per_month</code>. This node tells us that for the higher ‘miles_per_month’ vehicles the next best predictor is ‘variant’ and the cheapest variants (SE-L, SE-L Lux) have an estimated monthly depreciation of £230 and the others an estimated monthly depreciation of £268.</p>
<p>We can get a feel for how good our model is by calculating the mean absolute error.</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-14_fc6d23cfd6459a50d9fe6b1916903069">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb16" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb16-1">MAE <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(actual, predicted) { <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mean</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">abs</span>(actual <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> predicted))}</span></code></pre></div></div>
</div>
<p>Normally we would have divided our observations up into a training set and a testing set to perform this operation but here we will use mean absolute error to get a feel for how closely this model can predict our observed monthly depreciation.</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-15_4c620502759c40cda6fb25b2502073f2">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb17" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb17-1">predicted <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">predict</span>(model.rt, cars)</span>
<span id="cb17-2">actual <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>depreciation_per_month</span>
<span id="cb17-3"></span>
<span id="cb17-4"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">print</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">MAE</span>(actual, predicted))</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>[1] 14.05005</code></pre>
</div>
</div>
<p>So, on average, our model predicts the value of the monthly depreciation to within £14 of the observed depreciation. We could think of that as a measure of what we have lost by summarising the data into a structured and explainable model.</p>
<p>Let us look at what we would have obtained had we trained our model on a proportion of the data and then used the remaining observations to test its predictive accuracy.</p>
<p>We use <code>set.seed</code> to ensure that our results are reproducible. We take a random selection of 90% of our observations for the training set and use the remaining 10% to test the resulting model.</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-16_4b27b21b8032a896d7d2674905133948">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb19" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb19-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">set.seed</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">15151</span>)</span>
<span id="cb19-2">n <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> (cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">count</span>())[[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>]]</span>
<span id="cb19-3">cars_rand <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars[<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">order</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">runif</span>(n)),]</span>
<span id="cb19-4">split <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">round</span>(n<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.9</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span>
<span id="cb19-5"></span>
<span id="cb19-6">cars_train <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars_rand[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span>split, ]</span>
<span id="cb19-7">cars_test <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars_rand[(split<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span>n, ]</span>
<span id="cb19-8"></span>
<span id="cb19-9">model.rt.train <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rpart</span>(</span>
<span id="cb19-10">  depreciation_per_month <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> variant<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>engine<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>age_in_months<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>miles_per_month,</span>
<span id="cb19-11">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> cars_train</span>
<span id="cb19-12">)</span></code></pre></div></div>
</div>
<p>We can plot the decision tree of the training model as we did for the model we obtained from the full set of data.</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-17_3386b1dbb9868e3d23335182a6f2706c">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb20" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb20-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rpart.plot</span>(model.rt.train)</span></code></pre></div></div>
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://www.oldgang.net/notebooks/posts/car_prices_mazda3/03.modelling/modelling_files/figure-html/unnamed-chunk-17-1.png" class="img-fluid figure-img" width="672"></p>
</figure>
</div>
</div>
</div>
<p>Perhaps unsurprisingly, but somewhat reassuringly, the tree is similar to the previous one. The choice of variable to split on is initially the same, but after that the choice of variable is different. We have a similar number of leaf nodes: 12 vs 14, and the range of ‘depreciation_per_month’ values in the leaf nodes varies from 147 to 268 in one case and from 146 to 269 in the other case.</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-18_be62b7b7a41d53f5724c9495e21c7243">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb21" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb21-1">predicted <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">predict</span>(model.rt.train, cars_test)</span>
<span id="cb21-2">actual <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars_test<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>depreciation_per_month</span>
<span id="cb21-3"></span>
<span id="cb21-4"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">print</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">MAE</span>(actual, predicted))</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>[1] 13.54872</code></pre>
</div>
</div>
<p>The mean absolute error is roughly the same as the value that we obtained using the data that the model was trained on. This seems like a very small value for error in monthly depreciation, which suggests that our model is a good one.</p>
<p>We have seen how a regression tree can provide an alternative mechanism for understanding what drives monthly depreciation in our car dataset.</p>
</section>
<section id="linear-regression-vs-regression-tree" class="level3">
<h3 class="anchored" data-anchor-id="linear-regression-vs-regression-tree">Linear Regression vs Regression Tree</h3>
<p>We can compare the linear regression and the regression tree by training a new linear regression model on our training set and then calculating the mean absolute error of its predictions using the test data.</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-19_7759bfaeb03d1c491cd0591070c33b46">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb23" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb23-1">model.lm.train <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">lm</span>(</span>
<span id="cb23-2">  depreciation_per_month <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> variant<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>engine<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>age_in_months<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>miles_per_month,</span>
<span id="cb23-3">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data=</span>cars_train</span>
<span id="cb23-4">)</span></code></pre></div></div>
</div>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-20_665cd7bc231786aca15d88b45e354309">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb24" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb24-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summary</span>(model.lm.train)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>
Call:
lm(formula = depreciation_per_month ~ variant + engine + age_in_months + 
    miles_per_month, data = cars_train)

Residuals:
    Min      1Q  Median      3Q     Max 
-81.127 -10.965  -1.289  11.645  99.596 

Coefficients:
                       Estimate Std. Error t value Pr(&gt;|t|)    
(Intercept)          215.438461   7.496604  28.738  &lt; 2e-16 ***
variantSE-L Lux       -6.485232   5.129025  -1.264 0.207102    
variantSport Lux       3.082882   4.397253   0.701 0.483811    
variantGT Sport       18.638074   4.797640   3.885 0.000127 ***
variantGT Sport Tech  30.581669   5.209184   5.871 1.19e-08 ***
enginee-Skyactiv X    17.620848   3.148847   5.596 5.11e-08 ***
age_in_months         -1.622082   0.116082 -13.974  &lt; 2e-16 ***
miles_per_month        0.073328   0.005108  14.356  &lt; 2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 19.81 on 288 degrees of freedom
Multiple R-squared:  0.7165,    Adjusted R-squared:  0.7096 
F-statistic:   104 on 7 and 288 DF,  p-value: &lt; 2.2e-16</code></pre>
</div>
</div>
<p>A look at the model parameters confirms that it has hardly changed from the model that was fitted on the full set of data.</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-21_63a66086b030defacaccccd879286c89">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb26" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb26-1">predicted.rt <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">predict</span>(model.rt.train, cars_test)</span>
<span id="cb26-2">predicted.lm <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">predict</span>(model.lm.train, cars_test)</span>
<span id="cb26-3"></span>
<span id="cb26-4"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">print</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_glue</span>(</span>
<span id="cb26-5">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"MAE of regression tree:"</span>,</span>
<span id="cb26-6">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">round</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">MAE</span>(actual, predicted.rt),<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>))</span>
<span id="cb26-7">)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>MAE of regression tree:13.55</code></pre>
</div>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb28" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb28-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">print</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_glue</span>(</span>
<span id="cb28-2">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"MAE of linear regression:"</span>,</span>
<span id="cb28-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">round</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">MAE</span>(actual, predicted.lm),<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>))</span>
<span id="cb28-4">)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>MAE of linear regression:14.52</code></pre>
</div>
</div>
<p>The errors are almost identical, with the regression tree slightly out performing the linear regression.</p>
<p>We now have two useful models of monthly depreciation that can be used to examine what drives depreciation on used Mazda 3 cars in the UK.</p>
<p>In the next notebook we will look at a mechanism for creating a simple two-dimensional table to display aggregated car price data.</p>
<p>Next: <a href="../../../../notebooks/posts/car_prices_mazda3/04.tabulation/tabulation.html">Mazda 3 Price Data - Tabulation</a></p>
</section>
<section id="comparing-predictions" class="level3">
<h3 class="anchored" data-anchor-id="comparing-predictions">Comparing Predictions</h3>
<p>We can compare the predictions from the table given at the beginning of this notebook (Figure&nbsp;1), with the predictions taken from our regression tree (Figure&nbsp;2), with the predictions of our linear regression. In the last two cases we will use the models built with the full data set, <em>model.lm</em> and <em>model.rt</em>.</p>
<p>To do this we need to build a tibble containing a set of vehicle specifications for which we would like to predict the depreciation per month. We are interested in how each method predicts depreciation per month for vehicles between 6 and 36 months old, and for each combination of variant and engine. That gives us a total of <code>6 x 5 x 2 = 60</code> combinations but we need to remove those six invalid combinations that pair the “SE-L” variant with the “e-Skyactiv X”. After removing the invalid combinations we are left with 54 different combinations. We will assume that our vehicles will drive a modest 400 miles per month.</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-22_af637d9534370c9e20ac22cb90cdbdba">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb30" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb30-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(dplyr)</span>
<span id="cb30-2">variants <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">distinct</span>(variant)</span>
<span id="cb30-3">engines <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">distinct</span>(engine) </span>
<span id="cb30-4">age_in_months <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tibble</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">age_in_months =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">18</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">24</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">30</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">36</span>)) </span>
<span id="cb30-5">car.samples <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> variants <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb30-6">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">cross_join</span>(engines) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb30-7">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">cross_join</span>(age_in_months) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb30-8">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">miles_per_month =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">400</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb30-9">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!</span>(variant <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SE-L"</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> engine <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"e-Skyactiv X"</span>))</span></code></pre></div></div>
</div>
<p>We can start with the linear regression and the regression tree models and use their <code>predict</code> function to generate a predicted monthly depreciation for each of our 54 synthetic observations.</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-23_4ebd07c82f77ce5f655a38f7b2de0b7d">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb31" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb31-1">dpm.lm <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">predict</span>(model.lm, car.samples)</span>
<span id="cb31-2">dpm.rt <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">predict</span>(model.rt, car.samples)</span></code></pre></div></div>
</div>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-24_73b43b059698b64e69a4fa1bd6cafc59">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb32" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb32-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summary</span>(dpm.lm)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  183.4   212.2   228.6   228.9   244.9   281.6 </code></pre>
</div>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb34" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb34-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summary</span>(dpm.rt)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  147.5   202.1   228.8   224.2   254.8   254.8 </code></pre>
</div>
</div>
<p>Although the minimum and maximum depreciation_per_month values for the regression tree model are about £30 less than those for the linear regression, the interquartile range is almost identical and so is the median value.</p>
<p>To compare these with the predictions that we might make using the table shown in Figure&nbsp;1 is slightly more complicated. These predictions will have to ignore both age_in_months and miles_per_month because our table does not contain that information. Instead, they will use the median depreciation_per_month for the combination of variant and engine. We can see from the table that each valid combination of variant and engine is represented.</p>
<p>We will create a lookup tibble using a grouping of variant and engine, and for each group we will work out the median depreciation_per_month.</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-25_923f4884cd723eff563628c650095a1a">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb36" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb36-1">lookup <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb36-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(depreciation_per_month, variant, engine) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb36-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(variant, engine) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb36-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">median_dpm =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(depreciation_per_month))</span></code></pre></div></div>
</div>
<p>We can then obtain a prediction from the table for each of our observations by performing a left outer join between the observations tiblle and the lookup tibble.</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-26_0db540d378678176baa5fa87546568de">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb37" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb37-1">dpm.tab <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> car.samples <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb37-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">left_join</span>(lookup, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">by =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"variant"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"engine"</span>)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb37-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">depreciation_per_month =</span> median_dpm) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb37-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pull</span>(depreciation_per_month)</span></code></pre></div></div>
</div>
<p>We can now add the three prediction columns into our <code>car.samples</code> tibble and also add an observation number column to allow us to uniquely identify each row.</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-27_e57a9b659e5ae49b3d16864bfe862da2">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb38" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb38-1">car.samples <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> car.samples <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb38-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(</span>
<span id="cb38-3">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm.lm =</span> dpm.lm, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm.rt =</span> dpm.rt, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm.tab =</span> dpm.tab,</span>
<span id="cb38-4">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">obs =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">row_number</span>()</span>
<span id="cb38-5">  )</span></code></pre></div></div>
</div>
<p>Ordinarily we might randomise the order of the observations to ensure that no particular significance was given to their order. We would use code like this to perform the randomisation.</p>
<pre><code># We will not do this here because
# we want to see the pattern of our observations.
set.seed(0)
obs &lt;- sample.int(nrow(car.samples), replace=F)
car.samples$obs = obs</code></pre>
<p>But we will not do that here. Not doing the randomisation allows us to see in the predicted depreciation_per_month the effect of the order of the observations: variant then engine then age_in_months.</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-28_c6402c518b9783b8639544a11a15e409">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb40" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb40-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(patchwork)</span>
<span id="cb40-2">p1 <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> car.samples, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">mapping=</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> obs, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">shape=</span>age_in_months)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb40-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_point</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">mapping =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> dpm.lm), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">colour=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"red"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb40-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_shape_binned</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">labels =</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(x) <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">paste</span>(x, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"months"</span>)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb40-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggtitle</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Linear Regression"</span>)</span>
<span id="cb40-6">p2 <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> car.samples, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">mapping=</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> obs, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">shape=</span>age_in_months)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb40-7">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_point</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">mapping =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> dpm.rt), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">colour=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"red"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb40-8">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_shape_binned</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">labels =</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(x) <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">paste</span>(x, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"months"</span>)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb40-9">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggtitle</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Regression Tree"</span>)</span>
<span id="cb40-10">p3 <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> car.samples, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">mapping=</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> obs, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">shape=</span>age_in_months)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb40-11">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_point</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">mapping =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> dpm.tab), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">colour=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"red"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb40-12">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">scale_shape_binned</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">labels =</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(x) <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">paste</span>(x, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"months"</span>)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb40-13">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggtitle</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Tabulated Median"</span>)</span>
<span id="cb40-14">p1 <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> p2 <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> p3 <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb40-15">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">plot_layout</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">nrow =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">ncol =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">guides =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"collect"</span>)</span></code></pre></div></div>
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://www.oldgang.net/notebooks/posts/car_prices_mazda3/03.modelling/modelling_files/figure-html/unnamed-chunk-28-1.png" class="img-fluid figure-img" width="672"></p>
</figure>
</div>
</div>
</div>
<p>We can clearly see in the linear regression plot the clusters of variant and engine and, within them, the downward sloping decrease in depreciation per month as age_in_months increases.</p>
<p>In the regression tree plot we see clusters of variant and engine in one leaf and then vehicles with the same combination of variant and engine falling into a cluster with lower depreciation_per_month as the age_in_months increases.</p>
<p>For the tablulated median prediction, which does not consider age_in_months, we see a single cluster for each combination of engine and variant - as we would expect.</p>
<p>We recall from our earlier calculation of mean absolute error that the linear regression and the regression tree methods of predicting appeared to be equally as good at reducing error. From the shape of their predicted values shown in the charts above you might think that linear regression would have the edge over regression trees because it appears to smoothly interpolate rather than predict one of a discrete number of bucket values. But perhaps the disadvantage that the linear regression model has is that it has to come up with a linear expression that predicts depreciation_per_month across the complete range of variant, engine and miles_per_month. The regression tree model, is able to first home in on the effect a combination of the model variables has before choosing an appropriate aggregate value for that combination.</p>
<p>If we look at just how much the mean absolute difference is between predictions from these two models for each combination of variant and engine we see that there isn’t much to chose between them.</p>
<div class="cell" data-hash="modelling_cache/html/fig-difference_ced029320be19a41210cbb5dcdf8e815">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb41" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb41-1">car.samples <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb41-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(variant, engine, dpm.lm, dpm.rt) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb41-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(variant, engine) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb41-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>( <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">mae =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">MAE</span>(dpm.lm, dpm.rt)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb41-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pivot_wider</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">names_from=</span>engine, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_from=</span>mae) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb41-6">  knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
<div id="fig-difference" class="cell-output-display quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-difference-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">variant</th>
<th style="text-align: right;">e-Skyactiv G</th>
<th style="text-align: right;">e-Skyactiv X</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">SE-L</td>
<td style="text-align: right;">19</td>
<td style="text-align: right;">NA</td>
</tr>
<tr class="even">
<td style="text-align: left;">SE-L Lux</td>
<td style="text-align: right;">13</td>
<td style="text-align: right;">15</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Sport Lux</td>
<td style="text-align: right;">13</td>
<td style="text-align: right;">15</td>
</tr>
<tr class="even">
<td style="text-align: left;">GT Sport</td>
<td style="text-align: right;">10</td>
<td style="text-align: right;">11</td>
</tr>
<tr class="odd">
<td style="text-align: left;">GT Sport Tech</td>
<td style="text-align: right;">12</td>
<td style="text-align: right;">23</td>
</tr>
</tbody>
</table>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-difference-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;3: Mean absolute error difference between linear regression and regression trees.
</figcaption>
</figure>
</div>
</div>
<p>And if we introduce a breakdown into columns that show age_in_months we, also, see that the difference between the two models appears to have no obvious visual difference between low or high mileage vehicles.</p>
<div class="cell" data-hash="modelling_cache/html/fig-difference2_adec13f80db8c2767daa6a5c553e2146">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb42" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb42-1">car.samples <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb42-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(variant, engine, age_in_months, dpm.lm, dpm.rt) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb42-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(variant, engine, age_in_months) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb42-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>( <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">mae =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">MAE</span>(dpm.lm, dpm.rt)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb42-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pivot_wider</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">names_from=</span>age_in_months, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_from=</span>mae) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb42-6">  knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
<div id="fig-difference2" class="cell-output-display quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-difference2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">variant</th>
<th style="text-align: left;">engine</th>
<th style="text-align: right;">6</th>
<th style="text-align: right;">12</th>
<th style="text-align: right;">18</th>
<th style="text-align: right;">24</th>
<th style="text-align: right;">30</th>
<th style="text-align: right;">36</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">SE-L</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">22</td>
<td style="text-align: right;">31</td>
<td style="text-align: right;">12</td>
<td style="text-align: right;">3</td>
<td style="text-align: right;">7</td>
<td style="text-align: right;">39</td>
</tr>
<tr class="even">
<td style="text-align: left;">SE-L Lux</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">24</td>
<td style="text-align: right;">34</td>
<td style="text-align: right;">9</td>
<td style="text-align: right;">0</td>
<td style="text-align: right;">9</td>
<td style="text-align: right;">1</td>
</tr>
<tr class="odd">
<td style="text-align: left;">SE-L Lux</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">7</td>
<td style="text-align: right;">16</td>
<td style="text-align: right;">27</td>
<td style="text-align: right;">18</td>
<td style="text-align: right;">8</td>
<td style="text-align: right;">16</td>
</tr>
<tr class="even">
<td style="text-align: left;">Sport Lux</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">17</td>
<td style="text-align: right;">27</td>
<td style="text-align: right;">16</td>
<td style="text-align: right;">7</td>
<td style="text-align: right;">2</td>
<td style="text-align: right;">8</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Sport Lux</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">0</td>
<td style="text-align: right;">9</td>
<td style="text-align: right;">34</td>
<td style="text-align: right;">25</td>
<td style="text-align: right;">15</td>
<td style="text-align: right;">9</td>
</tr>
<tr class="even">
<td style="text-align: left;">GT Sport</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">3</td>
<td style="text-align: right;">12</td>
<td style="text-align: right;">5</td>
<td style="text-align: right;">5</td>
<td style="text-align: right;">14</td>
<td style="text-align: right;">23</td>
</tr>
<tr class="odd">
<td style="text-align: left;">GT Sport</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">15</td>
<td style="text-align: right;">6</td>
<td style="text-align: right;">22</td>
<td style="text-align: right;">13</td>
<td style="text-align: right;">3</td>
<td style="text-align: right;">6</td>
</tr>
<tr class="even">
<td style="text-align: left;">GT Sport Tech</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">9</td>
<td style="text-align: right;">0</td>
<td style="text-align: right;">16</td>
<td style="text-align: right;">7</td>
<td style="text-align: right;">2</td>
<td style="text-align: right;">35</td>
</tr>
<tr class="odd">
<td style="text-align: left;">GT Sport Tech</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">27</td>
<td style="text-align: right;">17</td>
<td style="text-align: right;">34</td>
<td style="text-align: right;">25</td>
<td style="text-align: right;">15</td>
<td style="text-align: right;">17</td>
</tr>
</tbody>
</table>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-difference2-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;4: Mean absolute error difference between linear regression and regression trees additionally broken down by age in months.
</figcaption>
</figure>
</div>
</div>
<p>So we have two mechanisms, linear regression and regression trees, for predicting the monthly depreciation of a Mazda 3 for a given variant, engine choice and age_in_months given an estimated mileage_per_month with neither model clearly better than the other.</p>
<p>Next: <a href="../../../../notebooks/posts/car_prices_mazda3/04.tabulation/tabulation.html">Mazda 3 Price Data - Tabulation</a></p>


</section>

 ]]></description>
  <category>R</category>
  <category>Car Price</category>
  <category>Mazda 3</category>
  <guid>https://www.oldgang.net/notebooks/posts/car_prices_mazda3/03.modelling/modelling.html</guid>
  <pubDate>Wed, 03 May 2023 01:00:00 GMT</pubDate>
</item>
<item>
  <title>Mazda 3 Price Data - Visualisation</title>
  <dc:creator>John Bates</dc:creator>
  <link>https://www.oldgang.net/notebooks/posts/car_prices_mazda3/02.visualisation/visualisation.html</link>
  <description><![CDATA[ 




<p>Given the cleaned dataset that we created in the companion notebook <a href="../../../../notebooks/posts/car_prices_mazda3/01.preparation/preparation.html">Mazda 3 Price Data - Preparation</a> we can now start to look more closely at the factors that influence used car depreciation for our chosen model, the Mazda 3.</p>
<p>We start by reading in the cars tibble that we created and saved.</p>
<div class="cell" data-hash="visualisation_cache/html/unnamed-chunk-1_188dd7ed734186cb58f41b9acffffb1b">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb1-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(tidyverse)</span>
<span id="cb1-2">cars <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">readRDS</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"../01.preparation/mazda3.rds"</span>)</span></code></pre></div></div>
</div>
<p>For the purposes of understanding depreciation we need to limit our data to used cars.</p>
<div class="cell" data-hash="visualisation_cache/html/unnamed-chunk-2_99ac86da7d3dd0a896cc34775d19e9ac">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb2-1">cars <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb2-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(new_used <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Used"</span>)</span></code></pre></div></div>
</div>
<p>We can see that the data consists of 362 rows on 14 columns.</p>
<div class="cell" data-hash="visualisation_cache/html/unnamed-chunk-3_c4ff87573e3f5bcd6529120441adac49">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb3-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str</span>(cars)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>tibble [362 × 14] (S3: tbl_df/tbl/data.frame)
 $ model                 : Factor w/ 1 level "Mazda 3": 1 1 1 1 1 1 1 1 1 1 ...
 $ variant               : Factor w/ 5 levels "SE-L","SE-L Lux",..: 5 2 2 5 3 3 4 4 2 4 ...
 $ drive                 : Factor w/ 1 level "2WD": 1 1 1 1 1 1 1 1 1 1 ...
 $ engine                : Factor w/ 2 levels "e-Skyactiv G",..: 1 1 1 1 1 1 1 1 1 2 ...
 $ new_used              : Factor w/ 2 levels "Used","New": 1 1 1 1 1 1 1 1 1 1 ...
 $ miles                 : num [1:362] 16843 12875 7891 28947 25664 ...
 $ miles_per_month       : num [1:362] 802 330 292 643 570 ...
 $ price                 : num [1:362] 21000 17250 19995 18995 16500 ...
 $ price_new             : num [1:362] 28285 24385 24385 28285 25485 ...
 $ depreciation          : num [1:362] 7285 7135 4390 9290 8985 ...
 $ depreciation_per_month: num [1:362] 347 183 163 206 200 ...
 $ fuel                  : Factor w/ 1 level "Petrol": 1 1 1 1 1 1 1 1 1 1 ...
 $ transmission          : Factor w/ 1 level "Manual": 1 1 1 1 1 1 1 1 1 1 ...
 $ age_in_months         : num [1:362] 18 36 24 42 42 42 30 42 12 24 ...</code></pre>
</div>
</div>
<p>A good place to start is to look at the relationships between the columns using a <code>pairs</code> plot. This plot uses the <code>pairs.panels</code> plot from the <code>psych</code> package to show, in addition to the normal pairs scatterplots, some information about the correlations between each displayed column.</p>
<p>The diagonal shows a histogram of the values of each variable. This gives us a visual indication of the distribution of values of that variable.</p>
<p>Above and below the diagonal are plots of each pairwise combinations of variable. The plots are overlaid by a linear regression line and a correlation ellipse. These indicate the general tendency of high values of one variable to be associated with high or low values of the other variable. A circular correlation ellipse indicates no such association.</p>
<div class="cell" data-hash="visualisation_cache/html/unnamed-chunk-4_9fac6d3ecfd8265a1e1a6b3c66070828">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb5-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"psych"</span>)</span>
<span id="cb5-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pairs.panels</span>(</span>
<span id="cb5-3">  cars[<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(</span>
<span id="cb5-4">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"variant"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"engine"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"age_in_months"</span>,</span>
<span id="cb5-5">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"miles"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"depreciation"</span></span>
<span id="cb5-6">  )],</span>
<span id="cb5-7">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">pch =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"."</span>,</span>
<span id="cb5-8">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">cor=</span>F,</span>
<span id="cb5-9">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">lm =</span> T,</span>
<span id="cb5-10">  )</span></code></pre></div></div>
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://www.oldgang.net/notebooks/posts/car_prices_mazda3/02.visualisation/visualisation_files/figure-html/unnamed-chunk-4-1.png" class="img-fluid figure-img" width="672"></p>
</figure>
</div>
</div>
</div>
<p>The most obvious observation is that depreciation increases with both age of the vehicle and the number of miles that it has been driven. That is not surprising, but it is a reminder that depreciation is not really the variable that we are interested in. A more interesting value to measure would be depreciation over time.</p>
<p>Similarly, a measure of miles, being so highly correlated with age_in_months might be more usefully expressed as miles_per_month. Fortunately, we recognised that when preparing the data and we do have two variables, miles_per_month and depreciation_per_month, which attempt to correct the effect that age has on miles driven and depreciation.</p>
<p>If we we create the pairs plot using miles_per_month in place of miles and depreciation_per_month in place of depreciation we see a different picture.</p>
<div class="cell" data-hash="visualisation_cache/html/unnamed-chunk-5_841e4fa327cc7974be1704678b076902">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb6-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"psych"</span>)</span>
<span id="cb6-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pairs.panels</span>(</span>
<span id="cb6-3">  cars[</span>
<span id="cb6-4">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"variant"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"engine"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"age_in_months"</span>,</span>
<span id="cb6-5">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"miles_per_month"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"depreciation_per_month"</span>)],</span>
<span id="cb6-6">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">pch =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"."</span>,</span>
<span id="cb6-7">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">cor=</span>F,</span>
<span id="cb6-8">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">lm =</span> T</span>
<span id="cb6-9">  )</span></code></pre></div></div>
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://www.oldgang.net/notebooks/posts/car_prices_mazda3/02.visualisation/visualisation_files/figure-html/unnamed-chunk-5-1.png" class="img-fluid figure-img" width="672"></p>
</figure>
</div>
</div>
</div>
<p>We see that a higher value of age_in_months is associated with a lower value of depreciation_per_month. That feels right, as a vehicle would be expected to lose value more quickly when it was newer. Surprisingly, we do not see that a higher value of miles_per_month is associated with a higher value of depreciation_per_month.</p>
<p>The plot of depreciation_per_month by variant suggests that there might be a high level of association between variant and depreciation_per_month but the fact that variant has only a small number of discrete values and the assumptions about variables being normally distributed mean that we should not put too much weight on the shape of the correlation ellipse for those two variables.</p>
<p>But it might be interesting to view the smoothed distribution of values of depreciation_per_month for each of the variants.</p>
<div class="cell" data-hash="visualisation_cache/html/unnamed-chunk-6_e68e4b6c3e26565d1065b3b1dcd6a5bd">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb7-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(ggridges)</span>
<span id="cb7-2"></span>
<span id="cb7-3">cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(</span>
<span id="cb7-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> depreciation_per_month, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> variant, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">fill =</span> variant, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">color =</span> variant)</span>
<span id="cb7-5">) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_density_ridges</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">alpha =</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">show.legend =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">FALSE</span>)</span></code></pre></div></div>
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://www.oldgang.net/notebooks/posts/car_prices_mazda3/02.visualisation/visualisation_files/figure-html/unnamed-chunk-6-1.png" class="img-fluid figure-img" width="672"></p>
</figure>
</div>
</div>
</div>
<p>It is noticeable how much narrower the range of depreciation per month is for the cheapest model - the SE-L variant. This is seen even more clearly with a box and whisker plot.</p>
<div class="cell" data-hash="visualisation_cache/html/unnamed-chunk-7_c1110a15e915d0d056db9eaa487a8307">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb8-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(</span>
<span id="cb8-2">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> cars,</span>
<span id="cb8-3">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">mapping =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> depreciation_per_month, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> variant)</span>
<span id="cb8-4">) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_boxplot</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">notch =</span> T) </span></code></pre></div></div>
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://www.oldgang.net/notebooks/posts/car_prices_mazda3/02.visualisation/visualisation_files/figure-html/unnamed-chunk-7-1.png" class="img-fluid figure-img" width="672"></p>
</figure>
</div>
</div>
</div>
<p>In this plot we have requested a <code>notch</code> on each plot. If the notches on two plots do not overlap then we can assume, with 95% confidence, that the medians are different. So between our variants the median depreciation_per_month is significantly different for all but the SE-L and SE-L Lux variants.</p>
<p>It doesn’t seem too surprising that there would be some vehicles with high levels of depreciation but the low levels are worth examining.</p>
<div class="cell" data-hash="visualisation_cache/html/unnamed-chunk-8_870e3ae579f32e8181c0cfdb903763f1">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb9-1">cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> </span>
<span id="cb9-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">arrange</span>(depreciation_per_month) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb9-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(model, variant, age_in_months, miles, price, price_new,</span>
<span id="cb9-4">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm =</span> depreciation_per_month) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb9-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">head</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code># A tibble: 5 × 7
  model   variant   age_in_months miles price price_new   dpm
  &lt;fct&gt;   &lt;fct&gt;             &lt;dbl&gt; &lt;dbl&gt; &lt;dbl&gt;     &lt;dbl&gt; &lt;dbl&gt;
1 Mazda 3 Sport Lux            36 19809 24078     27685  92.5
2 Mazda 3 SE-L                 42 17288 18567     23285 105. 
3 Mazda 3 SE-L                 36  9531 18961     23285 111. 
4 Mazda 3 GT Sport             42 24397 21779     27385 125. 
5 Mazda 3 SE-L                 72 11520 13400     23285 132. </code></pre>
</div>
</div>
<p>We can see that these are all vehicles with a low annual mileage.</p>
<p>The Price distribution by variant shows a potential problem with our data - only one variant (SE-L) is represented in the vehicles over the age of 50 months.</p>
<div class="cell" data-hash="visualisation_cache/html/unnamed-chunk-9_16e4c147dccc7aaf3f3ac67fc251a098">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb11-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(</span>
<span id="cb11-2">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> cars,</span>
<span id="cb11-3">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> age_in_months, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> price, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">color =</span> variant)</span>
<span id="cb11-4">) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_point</span>()</span></code></pre></div></div>
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://www.oldgang.net/notebooks/posts/car_prices_mazda3/02.visualisation/visualisation_files/figure-html/unnamed-chunk-9-1.png" class="img-fluid figure-img" width="672"></p>
</figure>
</div>
</div>
</div>
<p>This is seen more clearly when we plot age histograms by variant.</p>
<div class="cell" data-hash="visualisation_cache/html/unnamed-chunk-10_d27d5f9a5c16efc9a0052b4106051dab">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb12-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(</span>
<span id="cb12-2">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> cars,</span>
<span id="cb12-3">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> age_in_months)</span>
<span id="cb12-4">) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_histogram</span>() <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">facet_wrap</span>(cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>variant)</span></code></pre></div></div>
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://www.oldgang.net/notebooks/posts/car_prices_mazda3/02.visualisation/visualisation_files/figure-html/unnamed-chunk-10-1.png" class="img-fluid figure-img" width="672"></p>
</figure>
</div>
</div>
</div>
<p>Perhaps that helps to explain why we see a more narrow band of low depreciation_per_month in the SE-L variant.</p>
<p>We can examine the median values of depreciation_per_month by variant in tabular form and this looks to agree nicely with our boxplot above:</p>
<div class="cell" data-hash="visualisation_cache/html/unnamed-chunk-11_94a774abe8d4164884a78cc65ad1933a">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb13-1">cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb13-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm=</span>depreciation_per_month, variant, engine, drive) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb13-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(variant) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb13-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">n=</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">n</span>(), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">median_dpm =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(dpm, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">na.rm =</span> T)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb13-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">arrange</span>(median_dpm) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb13-6">  knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">variant</th>
<th style="text-align: right;">n</th>
<th style="text-align: right;">median_dpm</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">SE-L</td>
<td style="text-align: right;">41</td>
<td style="text-align: right;">161</td>
</tr>
<tr class="even">
<td style="text-align: left;">SE-L Lux</td>
<td style="text-align: right;">55</td>
<td style="text-align: right;">195</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Sport Lux</td>
<td style="text-align: right;">135</td>
<td style="text-align: right;">197</td>
</tr>
<tr class="even">
<td style="text-align: left;">GT Sport</td>
<td style="text-align: right;">77</td>
<td style="text-align: right;">220</td>
</tr>
<tr class="odd">
<td style="text-align: left;">GT Sport Tech</td>
<td style="text-align: right;">54</td>
<td style="text-align: right;">248</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>By engine across all variants and drives:</p>
<div class="cell" data-hash="visualisation_cache/html/unnamed-chunk-12_f6ca9b0e71f3fac30a0bcea1e6f9a681">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb14-1">cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb14-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm=</span>depreciation_per_month, variant, engine, drive) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb14-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(engine) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb14-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">n=</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">n</span>(), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">median_dpm =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(dpm, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">na.rm =</span> T)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb14-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">arrange</span>(median_dpm) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb14-6">  knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">engine</th>
<th style="text-align: right;">n</th>
<th style="text-align: right;">median_dpm</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">289</td>
<td style="text-align: right;">197</td>
</tr>
<tr class="even">
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">73</td>
<td style="text-align: right;">233</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>So the effect of the more expensive engine looks to be to increase the monthly depreciation by about £36 across all variants and drives.</p>
<p>Or by all combinations of variant and engine (ordered by median depreciation per month).</p>
<div class="cell" data-hash="visualisation_cache/html/unnamed-chunk-13_9340959df9f00ea4dad5a11d0c2a640e">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb15" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb15-1">cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb15-2">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(depreciation_per_month, variant, engine) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb15-3">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(variant, engine) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb15-4">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">n=</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">n</span>(), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">median_dpm =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(depreciation_per_month, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">na.rm =</span> T)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb15-5">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">arrange</span>(median_dpm) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb15-6">    knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">variant</th>
<th style="text-align: left;">engine</th>
<th style="text-align: right;">n</th>
<th style="text-align: right;">median_dpm</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">SE-L</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">41</td>
<td style="text-align: right;">161</td>
</tr>
<tr class="even">
<td style="text-align: left;">SE-L Lux</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">50</td>
<td style="text-align: right;">187</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Sport Lux</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">109</td>
<td style="text-align: right;">194</td>
</tr>
<tr class="even">
<td style="text-align: left;">GT Sport</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">50</td>
<td style="text-align: right;">207</td>
</tr>
<tr class="odd">
<td style="text-align: left;">SE-L Lux</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">5</td>
<td style="text-align: right;">213</td>
</tr>
<tr class="even">
<td style="text-align: left;">GT Sport Tech</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">39</td>
<td style="text-align: right;">223</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Sport Lux</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">26</td>
<td style="text-align: right;">229</td>
</tr>
<tr class="even">
<td style="text-align: left;">GT Sport</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">27</td>
<td style="text-align: right;">233</td>
</tr>
<tr class="odd">
<td style="text-align: left;">GT Sport Tech</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">15</td>
<td style="text-align: right;">249</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>It soon becomes clear that it is difficult to settle on a single method of determining which variables are most explanatory in understanding monthly depreciation. And also, exactly what the numerical effect of the choice of a particular variant or engine might be on monthly depreciation. We have conveniently ignored the effect of the age of the vehicle or the number of miles it has been driven and we know that these are likely to have a big effect.</p>
<p>In the next notebook we will look to model the effect of all of these variables on monthly depreciation.</p>
<p>Next: <a href="../../../../notebooks/posts/car_prices_mazda3/03.modelling/modelling.html">Mazda 3 Price Data - Modelling</a></p>



 ]]></description>
  <category>R</category>
  <category>Car Price</category>
  <category>Mazda 3</category>
  <guid>https://www.oldgang.net/notebooks/posts/car_prices_mazda3/02.visualisation/visualisation.html</guid>
  <pubDate>Tue, 02 May 2023 02:00:00 GMT</pubDate>
</item>
<item>
  <title>Mazda 3 Price Data - Preparation</title>
  <dc:creator>John Bates</dc:creator>
  <link>https://www.oldgang.net/notebooks/posts/car_prices_mazda3/01.preparation/preparation.html</link>
  <description><![CDATA[ 




<p>The aim of this notebook is to prepare an R dataframe for analysis. We start with some data that has been collected about car prices for a number of variants of the Mazda 3. The car prices are in £ Sterling and have been obtained from a number of sources.</p>
<p>The processing in this notebook will result in the creation of a serialisation of a cleaned dataframe to disk in R’s native RDS format.</p>
<p>This notebook follows the same series of steps as those described in more detail in the equivalent notebooks for the CX-30. The aim of this notebook is to rapidly repeat the same steps but for the Mazda 3 and so has much less narrative is given.</p>
<div class="cell" data-hash="preparation_cache/html/unnamed-chunk-1_39dded8ade370216893a4d936db09715">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb1-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(tidyverse)</span></code></pre></div></div>
</div>
<p>Our data is already in a CSV file on disk that we can read into a dataframe and then we can convert the dataframe into a tibble.</p>
<div class="cell" data-hash="preparation_cache/html/unnamed-chunk-2_989fde2a9a61dfa0d0a9c1c1874e43bf">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb2-1">cars <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">read_csv</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"mazda3.csv"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as_tibble</span>()</span></code></pre></div></div>
</div>
<p>Running <code>str</code> on the tibble shows that we have 669 rows on 7 columns.</p>
<div class="cell" data-hash="preparation_cache/html/unnamed-chunk-3_83df23807f507d019bf683230ef4ab87">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb3-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str</span>(cars)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>tibble [669 × 7] (S3: tbl_df/tbl/data.frame)
 $ rowno      : num [1:669] 1 2 3 4 5 6 7 8 9 10 ...
 $ id         : num [1:669] 2.02e+14 2.02e+14 2.02e+14 2.02e+14 2.02e+14 ...
 $ title      : chr [1:669] "Mazda3" "Mazda 3" "Mazda 3" "Mazda 3" ...
 $ subtitle   : chr [1:669] "2.0 e-Skyactiv G MHEV GT Sport Tech 5dr Leather Seats" "2.0 SKYACTIV G MHEV SE-L LUX 5DR" "SE-L LUX MHEV 2.0 5dr" "GT SPORT TECH MHEV 2.0 5dr" ...
 $ price      : num [1:669] 21000 17250 19995 18995 14490 ...
 $ spec       : chr [1:669] "2021 (71 reg) Hatchback 16,843 miles 2.0L 122PS Manual Petrol" "2020 (20 reg) Hatchback 12,875 miles 2.0L 122PS Manual Petrol 1 owner" "2021 (21 reg) Hatchback 7,891 miles 2.0L 122PS Manual Petrol" "2019 (69 reg) Hatchback 28,947 miles 2.0L 122PS Manual Petrol" ...
 $ advert_date: chr [1:669] "23/04/2023" "23/04/2023" "23/04/2023" "23/04/2023" ...</code></pre>
</div>
</div>
<p>Rename the title and subtitle columns.</p>
<div class="cell" data-hash="preparation_cache/html/unnamed-chunk-4_e25a20ecab2a0d8dfa1bc9cbde1126f5">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb5-1">cars <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rename</span>(</span>
<span id="cb5-2">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">model =</span> title,</span>
<span id="cb5-3">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">variant_detail =</span> subtitle</span>
<span id="cb5-4">)</span></code></pre></div></div>
</div>
<p>Examining the contents of the tibble we can see that there are some rows for models other than the Mazda 3.</p>
<div class="cell" data-hash="preparation_cache/html/unnamed-chunk-5_34985a378899758a58c4da01fb705a8e">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb6-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">table</span>(cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>model)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>
      Honda Civic          KIA Ceed           Mazda 2           Mazda 3 
               13                 3                 3               418 
Mazda 3 Hatchback            Mazda2            Mazda3  MAZDA3 HATCHBACK 
                2                 7               221                 2 </code></pre>
</div>
</div>
<p>Most are variations on the Mazda 3 model but the Honda, Kia and Mazda 2 rows will need to be removed. We can do this with the <code>filter</code> function of the <code>dplyr</code> package. We also don’t need the <code>rowno</code>, <code>id</code> or <code>advert_date</code> columns, so we remove them using the <code>select</code> function of the ‘dplyr’ package:</p>
<div class="cell" data-hash="preparation_cache/html/unnamed-chunk-6_820da58d7ac8edfe11d4a38afed79af0">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb8-1">cars <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb8-2">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(id, rowno, advert_date)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb8-3">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(</span>
<span id="cb8-4">        model <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Honda Civic"</span>, </span>
<span id="cb8-5">        model <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"KIA Ceed"</span>,</span>
<span id="cb8-6">        model <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Mazda2"</span>,</span>
<span id="cb8-7">        model <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Mazda 2"</span>,</span>
<span id="cb8-8">    )</span>
<span id="cb8-9"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">table</span>(cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>model)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>
          Mazda 3 Mazda 3 Hatchback            Mazda3  MAZDA3 HATCHBACK 
              418                 2               221                 2 </code></pre>
</div>
</div>
<p>It is easy to see from the remaining 4 columns that most of the useful information about the variant of the car lies within the <code>variant_detail</code> and the <code>spec</code> columns:</p>
<div class="cell" data-hash="preparation_cache/html/unnamed-chunk-7_e7a74002834a721ab982494ae9a51440">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb10-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">head</span>(cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>variant_detail)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>[1] "2.0 e-Skyactiv G MHEV GT Sport Tech 5dr Leather Seats"
[2] "2.0 SKYACTIV G MHEV SE-L LUX 5DR"                     
[3] "SE-L LUX MHEV 2.0 5dr"                                
[4] "GT SPORT TECH MHEV 2.0 5dr"                           
[5] "2.0 SKYACTIV-G Sport Nav Euro 6 (s/s) 5dr"            
[6] "2.0 Skyactiv G MHEV Sport Lux 5dr Petrol Hatchback"   </code></pre>
</div>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb12-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">head</span>(cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>spec)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>[1] "2021 (71 reg) Hatchback 16,843 miles 2.0L 122PS Manual Petrol"         
[2] "2020 (20 reg) Hatchback 12,875 miles 2.0L 122PS Manual Petrol 1 owner" 
[3] "2021 (21 reg) Hatchback 7,891 miles 2.0L 122PS Manual Petrol"          
[4] "2019 (69 reg) Hatchback 28,947 miles 2.0L 122PS Manual Petrol"         
[5] "2018 (18 reg) Hatchback 42,577 miles 2.0L 121PS Manual Petrol 2 owners"
[6] "2019 (69 reg) Hatchback 25,664 miles 2.0L 122PS Manual Petrol"         </code></pre>
</div>
</div>
<p>The task here is to identify the useful information that could be extracted from these two columns and then write functions to extract that information into new columns in the tibble. We show how this is done using the <code>mutate</code> function of the <code>dplyr</code> package which allows us to change the value of existing columns or to create new columns. Where the calculation of value for a column is anything other than trivial the work has been handed off to a function. You can see the definition of those functions by clicking the “show the code” link below.</p>
<div class="cell" data-hash="preparation_cache/html/unnamed-chunk-8_f4d020696fa6ddf11e228c7eb61545ee">
<details class="code-fold">
<summary>Show the code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb14-1">bhp_from_spec <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(spec){</span>
<span id="cb14-2">    bhp <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_extract</span>(spec, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"([:digit:]{3})(PS|BHP)"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">group =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)</span>
<span id="cb14-3">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">return</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as.numeric</span>(bhp))</span>
<span id="cb14-4">}</span>
<span id="cb14-5">miles_from_spec <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(spec){</span>
<span id="cb14-6">    miles <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_extract</span>(spec, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"([0-9,]+) miles"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">group =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)</span>
<span id="cb14-7">    miles <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_replace</span>(miles, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">","</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">""</span>)</span>
<span id="cb14-8">    miles <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">if_else</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">is.na</span>(miles), <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as.numeric</span>(miles))</span>
<span id="cb14-9">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">return</span>(miles)</span>
<span id="cb14-10">}</span>
<span id="cb14-11">new_used_from_spec_and_age <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(spec, age){</span>
<span id="cb14-12">    miles <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">miles_from_spec</span>(spec)</span>
<span id="cb14-13">    warranty <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_detect</span>(</span>
<span id="cb14-14">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_to_lower</span>(spec),</span>
<span id="cb14-15">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"full *manufacturer *warranty"</span></span>
<span id="cb14-16">    )</span>
<span id="cb14-17">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">return</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">if_else</span>(</span>
<span id="cb14-18">        miles <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> (warranty <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">TRUE</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> age <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>),</span>
<span id="cb14-19">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"New"</span>,</span>
<span id="cb14-20">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Used"</span></span>
<span id="cb14-21">    ))</span>
<span id="cb14-22">}</span>
<span id="cb14-23">reg_from_spec <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(spec){</span>
<span id="cb14-24">    matches <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_match</span>(spec, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"(?&lt;year&gt;[0-9]{4}) </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\\</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">((?&lt;reg&gt;[0-9]{2}) reg</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\\</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">)"</span>)</span>
<span id="cb14-25">    reg <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> matches[, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"reg"</span>]</span>
<span id="cb14-26">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">return</span>(reg)</span>
<span id="cb14-27">}</span>
<span id="cb14-28">year_from_spec <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(spec){</span>
<span id="cb14-29">    matches1 <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_match</span>(spec, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"(?&lt;year&gt;[0-9]{4}) </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\\</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">((?&lt;reg&gt;[0-9]{2}) reg</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\\</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">)"</span>)</span>
<span id="cb14-30">    year1 <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> matches1[, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"year"</span>]</span>
<span id="cb14-31">    matches2 <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_match</span>(spec, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"(?&lt;year&gt;20[12][0-9])"</span>)</span>
<span id="cb14-32">    year2 <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> matches2[, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"year"</span>]</span>
<span id="cb14-33">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">return</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">if_else</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">is.na</span>(year1), year2, year1))</span>
<span id="cb14-34">}</span>
<span id="cb14-35">age_in_months <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(reg){</span>
<span id="cb14-36">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#table_offset_in_months &lt;- interval(ymd("20230301"), today()) / dmonths() # nolint</span></span>
<span id="cb14-37">    table_offset_in_months <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span></span>
<span id="cb14-38">    months <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> table_offset_in_months <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb14-39">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">case_when</span>(</span>
<span id="cb14-40">        reg <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">23</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0</span>,</span>
<span id="cb14-41">        reg <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">72</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>,</span>
<span id="cb14-42">        reg <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">22</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.0</span>,</span>
<span id="cb14-43">        reg <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">71</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.5</span>,</span>
<span id="cb14-44">        reg <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">21</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2.0</span>,</span>
<span id="cb14-45">        reg <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">70</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2.5</span>,</span>
<span id="cb14-46">        reg <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">20</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.0</span>,</span>
<span id="cb14-47">        reg <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">69</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.5</span>,</span>
<span id="cb14-48">        reg <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">19</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">4.0</span>,</span>
<span id="cb14-49">        reg <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">68</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">4.5</span>,</span>
<span id="cb14-50">        reg <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">18</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">5.0</span>,</span>
<span id="cb14-51">        reg <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">67</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">5.5</span>,</span>
<span id="cb14-52">        reg <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">17</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">6.0</span>,</span>
<span id="cb14-53">        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.default =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">NA</span></span>
<span id="cb14-54">        )</span>
<span id="cb14-55">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">return</span>(months)</span>
<span id="cb14-56">}</span>
<span id="cb14-57">age_in_months_from_year <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(spec){</span>
<span id="cb14-58">    matches <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_match</span>(spec, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"(?&lt;year&gt;20[12][0-9])"</span>)</span>
<span id="cb14-59">    year <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> matches[, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"year"</span>]</span>
<span id="cb14-60">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#table_offset_in_months &lt;- interval(ymd("20230301"), today()) / dmonths() # nolint</span></span>
<span id="cb14-61">    table_offset_in_months <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span></span>
<span id="cb14-62">    months <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> table_offset_in_months <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb14-63">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">case_when</span>(</span>
<span id="cb14-64">        year <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2023</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0</span>,</span>
<span id="cb14-65">        year <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2022</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.0</span>,</span>
<span id="cb14-66">        year <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2021</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2.0</span>,</span>
<span id="cb14-67">        year <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2020</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.0</span>,</span>
<span id="cb14-68">        year <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2019</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">4.0</span>,</span>
<span id="cb14-69">        year <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2018</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">5.0</span>,</span>
<span id="cb14-70">        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.default =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">NA</span></span>
<span id="cb14-71">        )</span>
<span id="cb14-72">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">return</span>(months)</span>
<span id="cb14-73"></span>
<span id="cb14-74">}</span>
<span id="cb14-75">variant_from_detail <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(variant_detail){</span>
<span id="cb14-76">    detail <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_to_lower</span>(variant_detail)</span>
<span id="cb14-77">    test <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> \(pat) <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_detect</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fixed</span>(detail), pat)</span>
<span id="cb14-78">    variant <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">case_when</span>(</span>
<span id="cb14-79">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">test</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"se-l lux"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SE-L Lux"</span>,</span>
<span id="cb14-80">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">test</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"se-l"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SE-L"</span>,</span>
<span id="cb14-81">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">test</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sport lux"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Sport Lux"</span>,</span>
<span id="cb14-82">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">test</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"gt sport tech"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"GT Sport Tech"</span>,</span>
<span id="cb14-83">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">test</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"gt sport"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"GT Sport"</span>,</span>
<span id="cb14-84">        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.default =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_glue</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"XXXX: {variant_detail}"</span>)</span>
<span id="cb14-85">    )</span>
<span id="cb14-86">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">return</span>(variant)</span>
<span id="cb14-87">}</span>
<span id="cb14-88">drive_from_detail <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(variant_detail){</span>
<span id="cb14-89">    detail <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_to_lower</span>(variant_detail)</span>
<span id="cb14-90">    test <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> \(pat) <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_detect</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fixed</span>(detail), pat)</span>
<span id="cb14-91">    drive <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">case_when</span>(</span>
<span id="cb14-92">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">test</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"awd"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"AWD"</span>,</span>
<span id="cb14-93">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">test</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"4wd"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"AWD"</span>,</span>
<span id="cb14-94">        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.default =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"2WD"</span></span>
<span id="cb14-95">    )</span>
<span id="cb14-96">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">return</span>(drive)</span>
<span id="cb14-97">}</span>
<span id="cb14-98">engine_from_detail_and_bhp <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(variant_detail, bhp) {</span>
<span id="cb14-99">    detail <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_to_lower</span>(variant_detail)</span>
<span id="cb14-100">    test <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> \(pat) <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_detect</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fixed</span>(detail), pat)</span>
<span id="cb14-101">    variant1 <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">case_when</span>(</span>
<span id="cb14-102">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">test</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"skyactiv x"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"e-Skyactiv X"</span>,</span>
<span id="cb14-103">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">test</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"skyactiv-x"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"e-Skyactiv X"</span>,</span>
<span id="cb14-104">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">test</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"skyactiv g"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"e-Skyactiv G"</span>,</span>
<span id="cb14-105">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">test</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"skyactiv-g"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"e-Skyactiv G"</span>,</span>
<span id="cb14-106">    )</span>
<span id="cb14-107">    variant2 <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">if_else</span>(</span>
<span id="cb14-108">        bhp <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"High"</span>,</span>
<span id="cb14-109">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"e-Skyactiv X"</span>,</span>
<span id="cb14-110">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"e-Skyactiv G"</span></span>
<span id="cb14-111">    )</span>
<span id="cb14-112">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">return</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">if_else</span>(</span>
<span id="cb14-113">        <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">is.na</span>(variant1),</span>
<span id="cb14-114">        variant1,</span>
<span id="cb14-115">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">if_else</span>(</span>
<span id="cb14-116">            <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">is.na</span>(variant2),</span>
<span id="cb14-117">            variant2,</span>
<span id="cb14-118">            <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_glue</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"XXXX: {variant_detail}"</span>)</span>
<span id="cb14-119">        )</span>
<span id="cb14-120">    ))</span>
<span id="cb14-121">}</span>
<span id="cb14-122">price_new_from_variant_and_engine <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(variant, engine) { <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># nolint</span></span>
<span id="cb14-123">    key <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">paste</span>(variant, engine, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">sep =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"/"</span>)</span>
<span id="cb14-124">    key <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_to_lower</span>(key)</span>
<span id="cb14-125">    price_new <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">case_when</span>(</span>
<span id="cb14-126">        key <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"se-l lux/e-skyactiv g"</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"24385"</span>,</span>
<span id="cb14-127">        key <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"se-l lux/e-skyactiv x"</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"26285"</span>,</span>
<span id="cb14-128">        key <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"se-l/e-skyactiv g"</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"23285"</span>,</span>
<span id="cb14-129">        key <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sport lux/e-skyactiv g"</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"25485"</span>,</span>
<span id="cb14-130">        key <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sport lux/e-skyactiv x"</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"27685"</span>,</span>
<span id="cb14-131">        key <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"gt sport/e-skyactiv g"</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"27385"</span>,</span>
<span id="cb14-132">        key <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"gt sport/e-skyactiv x"</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"29585"</span>,</span>
<span id="cb14-133">        key <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"gt sport tech/e-skyactiv g"</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"28285"</span>,</span>
<span id="cb14-134">        key <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"gt sport tech/e-skyactiv x"</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"30485"</span>,</span>
<span id="cb14-135">        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.default =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_glue</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"XXXX: {variant} {engine}"</span>)</span>
<span id="cb14-136">    )</span>
<span id="cb14-137">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">return</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as.numeric</span>(price_new))</span>
<span id="cb14-138">}</span></code></pre></div></div>
</details>
</div>
<p>The main body of the code uses those functions to determine the value of a number of new columns.</p>
<div class="cell" data-hash="preparation_cache/html/unnamed-chunk-9_b53492fc6a7bbc91d731b54a0b75815b">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb15" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb15-1">cars <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb15-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(</span>
<span id="cb15-3">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">model =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Mazda 3"</span>,</span>
<span id="cb15-4">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">variant =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">variant_from_detail</span>(variant_detail),</span>
<span id="cb15-5">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">drive =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">drive_from_detail</span>(variant_detail),</span>
<span id="cb15-6">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">fuel =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">if_else</span>(</span>
<span id="cb15-7">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_detect</span>(spec, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Petrol"</span>),</span>
<span id="cb15-8">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Petrol"</span>,</span>
<span id="cb15-9">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Diesel"</span>,</span>
<span id="cb15-10">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Unknown"</span></span>
<span id="cb15-11">    ),</span>
<span id="cb15-12">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">price =</span> price,</span>
<span id="cb15-13">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">transmission =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">if_else</span>(</span>
<span id="cb15-14">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_detect</span>(spec, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Manual"</span>),</span>
<span id="cb15-15">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Manual"</span>,</span>
<span id="cb15-16">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Automatic"</span>,</span>
<span id="cb15-17">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Unknown"</span></span>
<span id="cb15-18">    ),</span>
<span id="cb15-19">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">bhp =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">if_else</span>(</span>
<span id="cb15-20">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">bhp_from_spec</span>(spec) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">175</span>,</span>
<span id="cb15-21">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"High"</span>,</span>
<span id="cb15-22">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Low"</span></span>
<span id="cb15-23">    ),</span>
<span id="cb15-24">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">engine =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">engine_from_detail_and_bhp</span>(variant_detail, bhp),</span>
<span id="cb15-25">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">price_new =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">price_new_from_variant_and_engine</span>(variant, engine), <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># nolint: line_length_linter.</span></span>
<span id="cb15-26">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">miles =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">miles_from_spec</span>(spec),</span>
<span id="cb15-27">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">reg =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">reg_from_spec</span>(spec),</span>
<span id="cb15-28">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">year =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">year_from_spec</span>(spec),</span>
<span id="cb15-29">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">age_in_months =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">if_else</span>(</span>
<span id="cb15-30">        <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">is.na</span>(reg),</span>
<span id="cb15-31">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">age_in_months</span>(reg),</span>
<span id="cb15-32">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">age_in_months_from_year</span>(spec)</span>
<span id="cb15-33">    ),</span>
<span id="cb15-34">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">mid_age_in_months =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">if_else</span>(</span>
<span id="cb15-35">        <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">is.na</span>(reg),</span>
<span id="cb15-36">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">age_in_months</span>(reg)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>,</span>
<span id="cb15-37">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">age_in_months_from_year</span>(spec)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span></span>
<span id="cb15-38">    ),</span>
<span id="cb15-39">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">new_used =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">new_used_from_spec_and_age</span>(spec, age_in_months),</span>
<span id="cb15-40">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">spec =</span> spec,</span>
<span id="cb15-41">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">depreciation =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">if_else</span>(price_new <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> price, price_new <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> price, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>),</span>
<span id="cb15-42">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">depreciation_per_month =</span> depreciation <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> mid_age_in_months,</span>
<span id="cb15-43">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">miles_per_month =</span> miles <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> mid_age_in_months</span>
<span id="cb15-44">)</span></code></pre></div></div>
</div>
<p>We now have a tibble with many more columns:</p>
<div class="cell" data-hash="preparation_cache/html/unnamed-chunk-10_f39fac03385046d4f5413d4746ae2a07">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb16" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb16-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str</span>(cars)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>tibble [643 × 20] (S3: tbl_df/tbl/data.frame)
 $ model                 : chr [1:643] "Mazda 3" "Mazda 3" "Mazda 3" "Mazda 3" ...
 $ variant_detail        : chr [1:643] "2.0 e-Skyactiv G MHEV GT Sport Tech 5dr Leather Seats" "2.0 SKYACTIV G MHEV SE-L LUX 5DR" "SE-L LUX MHEV 2.0 5dr" "GT SPORT TECH MHEV 2.0 5dr" ...
 $ price                 : num [1:643] 21000 17250 19995 18995 14490 ...
 $ spec                  : chr [1:643] "2021 (71 reg) Hatchback 16,843 miles 2.0L 122PS Manual Petrol" "2020 (20 reg) Hatchback 12,875 miles 2.0L 122PS Manual Petrol 1 owner" "2021 (21 reg) Hatchback 7,891 miles 2.0L 122PS Manual Petrol" "2019 (69 reg) Hatchback 28,947 miles 2.0L 122PS Manual Petrol" ...
 $ variant               : 'glue' chr [1:643] "GT Sport Tech" "SE-L Lux" "SE-L Lux" "GT Sport Tech" ...
 $ drive                 : chr [1:643] "2WD" "2WD" "2WD" "2WD" ...
 $ fuel                  : chr [1:643] "Petrol" "Petrol" "Petrol" "Petrol" ...
 $ transmission          : chr [1:643] "Manual" "Manual" "Manual" "Manual" ...
 $ bhp                   : chr [1:643] "Low" "Low" "Low" "Low" ...
 $ engine                : 'glue' chr [1:643] "e-Skyactiv G" "e-Skyactiv G" "e-Skyactiv G" "e-Skyactiv G" ...
 $ price_new             : num [1:643] 28285 24385 24385 28285 NA ...
 $ miles                 : num [1:643] 16843 12875 7891 28947 42577 ...
 $ reg                   : chr [1:643] "71" "20" "21" "69" ...
 $ year                  : chr [1:643] "2021" "2020" "2021" "2019" ...
 $ age_in_months         : num [1:643] 18 36 24 42 60 42 24 42 30 NA ...
 $ mid_age_in_months     : num [1:643] 21 39 27 45 63 45 27 45 33 NA ...
 $ new_used              : chr [1:643] "Used" "Used" "Used" "Used" ...
 $ depreciation          : num [1:643] 7285 7135 4390 9290 NA ...
 $ depreciation_per_month: num [1:643] 347 183 163 206 NA ...
 $ miles_per_month       : num [1:643] 802 330 292 643 676 ...</code></pre>
</div>
</div>
<p>The columns <code>variant_detail</code> and <code>spec</code> are now redundant and we will drop them from the tibble later. But the determination of new column values has thrown up a few records for which we don’t have enough information and we will delete those rows.</p>
<p>The Mazda site defines only the models “SE-L”, “SE-L Lux”, “Sport Lux”, “GT Sport”, and “GT Sport Tech”. We make use of the fact that the determination of price_new will fail if we have not recognised the variant</p>
<div class="cell" data-hash="preparation_cache/html/unnamed-chunk-11_e4da0234e6e04aaceecfe273325ac7aa">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb18" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb18-1">(cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">is.na</span>(price_new)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">count</span>())[[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>]]</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>[1] 137</code></pre>
</div>
</div>
<p>We have written a function to determine the new price of each of the vehicles. The new price can be found from the Mazda site using a combination of variant, and engine size. We want to be able to use the new price of a given vehicle to help us estimate how much the vehicle has depreciated over time.</p>
<p>The above query shows us that for 137 vehicles we were unable to find a price for the given combination of these column values. We will also remove record for which we cannot determine the age_in_months and those for all-wheel-drive vehicles.</p>
<div class="cell" data-hash="preparation_cache/html/unnamed-chunk-12_8e389216f41fc48d58ee1ac91f8c3431">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb20" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb20-1">cars <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb20-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(</span>
<span id="cb20-3">    <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">is.na</span>(price_new),</span>
<span id="cb20-4">    <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">is.na</span>(age_in_months),</span>
<span id="cb20-5">    drive <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"AWD"</span></span>
<span id="cb20-6">)</span></code></pre></div></div>
</div>
<p>Next we create factors for those columns that are to be treated as such:</p>
<div class="cell" data-hash="preparation_cache/html/unnamed-chunk-13_c6e7f9798b496574bc88609e72663e2c">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb21" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb21-1">cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>model <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as_factor</span>(cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>model)</span>
<span id="cb21-2">cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>variant <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span></span>
<span id="cb21-3">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as_factor</span>(cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>variant) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb21-4">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fct_reorder</span>(cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>price_new)</span>
<span id="cb21-5">cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>drive <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as_factor</span>(cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>drive)</span>
<span id="cb21-6">cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>engine <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span></span>
<span id="cb21-7">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as_factor</span>(cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>engine) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb21-8">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fct_reorder</span>(cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>price_new)</span>
<span id="cb21-9">cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>new_used <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as_factor</span>(cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>new_used)</span>
<span id="cb21-10">cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>reg <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as_factor</span>(cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>reg)</span>
<span id="cb21-11">cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>fuel <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as_factor</span>(cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>fuel)</span>
<span id="cb21-12">cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>transmission <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as_factor</span>(cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>transmission)</span>
<span id="cb21-13">cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>bhp <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as_factor</span>(cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>bhp)</span></code></pre></div></div>
</div>
<p>So now we have the following numbers of vehicles of each variant remaining.</p>
<div class="cell" data-hash="preparation_cache/html/unnamed-chunk-14_6b841684116ccc9fdff012342dcfbf3a">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb22" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb22-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">table</span>(cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>variant)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>
         SE-L      SE-L Lux     Sport Lux      GT Sport GT Sport Tech 
           41            57           143            81            57 </code></pre>
</div>
</div>
<p>We select the final set of columns that we want to see in our tibble and we save the tibble to a disk file for use in later analyses.</p>
<div class="cell" data-hash="preparation_cache/html/unnamed-chunk-15_0adb4764ffaa5be35a9613a12ff227b4">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb24" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb24-1">cars <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb24-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(</span>
<span id="cb24-3">    model, variant, drive, engine, new_used,</span>
<span id="cb24-4">    miles, miles_per_month,</span>
<span id="cb24-5">    price, price_new,</span>
<span id="cb24-6">    depreciation, depreciation_per_month,</span>
<span id="cb24-7">    fuel, transmission,</span>
<span id="cb24-8">    age_in_months</span>
<span id="cb24-9">))</span>
<span id="cb24-10"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">saveRDS</span>(cars, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">file=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"mazda3.rds"</span>)</span></code></pre></div></div>
</div>
<p>Next: <a href="../../../../notebooks/posts/car_prices_mazda3/02.visualisation/visualisation.html">Mazda 3 Price Data - Visualisation</a></p>



 ]]></description>
  <category>R</category>
  <category>Car Price</category>
  <category>Mazda 3</category>
  <guid>https://www.oldgang.net/notebooks/posts/car_prices_mazda3/01.preparation/preparation.html</guid>
  <pubDate>Tue, 02 May 2023 01:00:00 GMT</pubDate>
</item>
<item>
  <title>Mazda CX-30 Price Data - Tabulation</title>
  <dc:creator>John Bates</dc:creator>
  <link>https://www.oldgang.net/notebooks/posts/car_prices/04.tabulation/tabulation.html</link>
  <description><![CDATA[ 




<p>This notebook looks at methods of tabulating the data in the car price data dataset (see <a href="../../../../notebooks/posts/car_prices/01.preparation/preparation.html">Car Price Data - Preparation</a>). The aim is to look at ways of presenting simple one or two dimensional summary tables with as little code as possible. All of the manipulation of data will be done using functions from the <code>dplyr</code> or <code>tidyr</code> packages, both of which are part of the <code>tidyverse</code> umbrella package.</p>
<p>I feel sure that there should be a simple R package for creating simple tables, with aggregated values, from a dataframe. But, at the time of writing, I could not find one that was simple or mature enough to persuade me to use it. Hopefully that will change soon.</p>
<p>In the meantime, I demonstrate one technique that uses the <code>tidyverse</code> packages to build a two-dimensional table that handles the calculation and display of aggregated data and includes the correct calculation of aggregate values for row, column and grand totals.</p>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Note
</div>
</div>
<div class="callout-body-container callout-body">
<p>In this notebook where we want to talk about the rows or columns of a displayed table we will use the terms row dimension and column dimension. Using dimension, rather than variable or column, will help make it clear that we are talking about the horizontal or vertical dimension of a displayed table rather than a property of a dataframe or underlying model.</p>
</div>
</div>
<p>The technique for creating a table is to build a dataframe that holds the entire table structure and then to display it using the appropriate mechanism. Output in this notebook is by means of the <code>knitr::kable</code> function.</p>
<p>We start by reading in the cars tibble that we created and saved.</p>
<div class="cell" data-hash="tabulation_cache/html/unnamed-chunk-1_d4b10ff40f83956d2edc129da9180d69">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb1-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(tidyverse)</span>
<span id="cb1-2">cars <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">readRDS</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"../01.preparation/mazda.rds"</span>)</span></code></pre></div></div>
</div>
<p>And then restrict it to just Used cars, and cars for which we were able to calculate the monthly depreciation.</p>
<div class="cell" data-hash="tabulation_cache/html/unnamed-chunk-2_d62e1c9247d0e5aaca55990ab2d1cb8f">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb2-1">cars <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb2-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(new_used <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Used"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb2-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">is.na</span>(depreciation_per_month))</span></code></pre></div></div>
</div>
<p>Suppose that we would like to create a simple ordered, one-dimensional listing that shows the count and median monthly depreciation for each combination of variant, engine, and drive.</p>
<p>We choose the columns that we are interested in using the <code>select</code> function.</p>
<p>Then we use <code>group_by</code> followed by <code>summarise</code> to reduce the data. Our output will contain a row for each combination of the columns named in the call to <code>group_by</code> - these columns will be shown in the output.</p>
<p>In addition, any values that we define in the call to <code>summarize</code> will also show up in the output in columns in the listing immediately following the group-by columns. Their values will be calculated for each of the groups - each of the combinations of the group-by columns. The aggregating functions can make use of any of the columns that we have selected from the dataframe. The special function <code>n()</code> returns the current group size.</p>
<p>The <code>arrange</code> function orders the output into ascending or descending order based on the values of one or more columns.</p>
<div class="cell" data-hash="tabulation_cache/html/unnamed-chunk-3_97c5ca62b5cf48274186d75865d9f23b">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb3-1">cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb3-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(depreciation_per_month, variant, engine, drive) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb3-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(variant, engine, drive) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb3-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">n=</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">n</span>(), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">median_dpm =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(depreciation_per_month)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb3-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">arrange</span>(median_dpm) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb3-6">  knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">variant</th>
<th style="text-align: left;">engine</th>
<th style="text-align: left;">drive</th>
<th style="text-align: right;">n</th>
<th style="text-align: right;">median_dpm</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">SE-L Lux</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: left;">2WD</td>
<td style="text-align: right;">48</td>
<td style="text-align: right;">186</td>
</tr>
<tr class="even">
<td style="text-align: left;">SE-L</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: left;">2WD</td>
<td style="text-align: right;">32</td>
<td style="text-align: right;">195</td>
</tr>
<tr class="odd">
<td style="text-align: left;">SE-L Lux</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: left;">2WD</td>
<td style="text-align: right;">27</td>
<td style="text-align: right;">218</td>
</tr>
<tr class="even">
<td style="text-align: left;">Sport Lux</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: left;">2WD</td>
<td style="text-align: right;">88</td>
<td style="text-align: right;">223</td>
</tr>
<tr class="odd">
<td style="text-align: left;">GT Sport</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: left;">2WD</td>
<td style="text-align: right;">27</td>
<td style="text-align: right;">233</td>
</tr>
<tr class="even">
<td style="text-align: left;">Sport Lux</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: left;">2WD</td>
<td style="text-align: right;">89</td>
<td style="text-align: right;">241</td>
</tr>
<tr class="odd">
<td style="text-align: left;">GT Sport Tech</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: left;">2WD</td>
<td style="text-align: right;">13</td>
<td style="text-align: right;">252</td>
</tr>
<tr class="even">
<td style="text-align: left;">GT Sport</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: left;">2WD</td>
<td style="text-align: right;">60</td>
<td style="text-align: right;">253</td>
</tr>
<tr class="odd">
<td style="text-align: left;">GT Sport Tech</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: left;">2WD</td>
<td style="text-align: right;">82</td>
<td style="text-align: right;">285</td>
</tr>
<tr class="even">
<td style="text-align: left;">GT Sport</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: left;">AWD</td>
<td style="text-align: right;">12</td>
<td style="text-align: right;">304</td>
</tr>
<tr class="odd">
<td style="text-align: left;">GT Sport Tech</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: left;">AWD</td>
<td style="text-align: right;">13</td>
<td style="text-align: right;">306</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>If we want to create a two-dimensional table we need to use the <code>pivot_wider</code> function to declare which column of the dataframe will appear at the table column dimension and what values will be displayed in the cells of the table.</p>
<div class="cell" data-hash="tabulation_cache/html/unnamed-chunk-4_d3a7c388737f2ab954e971785e07b3d3">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb4-1">cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb4-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(variant, engine, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm=</span>depreciation_per_month) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb4-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(variant, engine) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb4-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>( <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(dpm)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb4-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pivot_wider</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">names_from=</span>engine, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_from=</span>dpm) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb4-6">  knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">variant</th>
<th style="text-align: right;">e-Skyactiv G</th>
<th style="text-align: right;">e-Skyactiv X</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">SE-L</td>
<td style="text-align: right;">195</td>
<td style="text-align: right;">NA</td>
</tr>
<tr class="even">
<td style="text-align: left;">SE-L Lux</td>
<td style="text-align: right;">186</td>
<td style="text-align: right;">218</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Sport Lux</td>
<td style="text-align: right;">223</td>
<td style="text-align: right;">241</td>
</tr>
<tr class="even">
<td style="text-align: left;">GT Sport</td>
<td style="text-align: right;">233</td>
<td style="text-align: right;">261</td>
</tr>
<tr class="odd">
<td style="text-align: left;">GT Sport Tech</td>
<td style="text-align: right;">252</td>
<td style="text-align: right;">291</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>We have seen that without using <code>pivot_wider</code> we get a listing output that includes our two group-by columns (variant and engine). We use the <code>names_from</code> argument to <code>pivot_wider</code> to declare the dataframe column that will provide the values for the column dimension of our table. We use the <code>values_from</code> argument to <code>pivot_wider</code> to declare the dataframe column whose values will be displayed in the cells of the table. The remaining group-by column will provide the values for the row dimension of the table.</p>
<div class="cell" data-hash="tabulation_cache/html/unnamed-chunk-5_dc0b82ca0755fa2ee8f95bb02d957e66">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb5-1">cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb5-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(variant, engine, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm=</span>depreciation_per_month) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb5-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(variant, engine) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb5-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>( <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(dpm)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb5-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pivot_wider</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">names_from=</span>engine, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_from=</span>dpm) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb5-6">  knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">variant</th>
<th style="text-align: right;">e-Skyactiv G</th>
<th style="text-align: right;">e-Skyactiv X</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">SE-L</td>
<td style="text-align: right;">195</td>
<td style="text-align: right;">NA</td>
</tr>
<tr class="even">
<td style="text-align: left;">SE-L Lux</td>
<td style="text-align: right;">186</td>
<td style="text-align: right;">218</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Sport Lux</td>
<td style="text-align: right;">223</td>
<td style="text-align: right;">241</td>
</tr>
<tr class="even">
<td style="text-align: left;">GT Sport</td>
<td style="text-align: right;">233</td>
<td style="text-align: right;">261</td>
</tr>
<tr class="odd">
<td style="text-align: left;">GT Sport Tech</td>
<td style="text-align: right;">252</td>
<td style="text-align: right;">291</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>In the above table we have reduced the dataframe to a variant value on the rows, an engine name on the columns and the median monthly depreciation values for each combination of row value and column value in each of the cells.</p>
<p>In general, the procedure is to group the data by the two variables that are to make up the row and column values. Then, summarise the group by the statistic that you want to display in the table cells.</p>
<p>Specify the variable that you want to use to supply the column values of the table in the <code>names_from</code> argument to <code>pivot_wider</code> and the summary statistic that you want to use to supply the cell values of the table in the <code>values_from</code> argument to <code>pivot_wider</code>.</p>
<p>By default, missing values will be shown in the table as <code>NA</code>. If you want them to be replaced by an alternative value then the <code>values_fill</code> argument can supply the replacement.</p>
<p>If you need to represent more than two dimensions in the table you can combine two into the columns by providing them both to <code>names_from</code> but this only really works if the number of values are relatively small and the length of the values of the columns are also relatively short.</p>
<div class="cell" data-hash="tabulation_cache/html/unnamed-chunk-6_8b8bf7d2bc6440634d0c62f8b5601eac">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb6-1">cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb6-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(variant, engine, drive, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm=</span>depreciation_per_month) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb6-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(variant, engine, drive) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb6-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">n =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">n</span>()) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb6-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pivot_wider</span>(</span>
<span id="cb6-6">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">names_from=</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(engine,drive), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_from=</span>n, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_fill=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span></span>
<span id="cb6-7">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb6-8">  knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">variant</th>
<th style="text-align: right;">e-Skyactiv G_2WD</th>
<th style="text-align: right;">e-Skyactiv X_2WD</th>
<th style="text-align: right;">e-Skyactiv X_AWD</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">SE-L</td>
<td style="text-align: right;">32</td>
<td style="text-align: right;">0</td>
<td style="text-align: right;">0</td>
</tr>
<tr class="even">
<td style="text-align: left;">SE-L Lux</td>
<td style="text-align: right;">48</td>
<td style="text-align: right;">27</td>
<td style="text-align: right;">0</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Sport Lux</td>
<td style="text-align: right;">88</td>
<td style="text-align: right;">89</td>
<td style="text-align: right;">0</td>
</tr>
<tr class="even">
<td style="text-align: left;">GT Sport</td>
<td style="text-align: right;">27</td>
<td style="text-align: right;">60</td>
<td style="text-align: right;">12</td>
</tr>
<tr class="odd">
<td style="text-align: left;">GT Sport Tech</td>
<td style="text-align: right;">13</td>
<td style="text-align: right;">82</td>
<td style="text-align: right;">13</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>A better solution is to use the longer variables as table rows and use the smallest and shortest variable as the table columns.</p>
<div class="cell" data-hash="tabulation_cache/html/unnamed-chunk-7_6f516f7415387b90c126af9cca61ba78">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb7-1">cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb7-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(variant, engine, drive, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm=</span>depreciation_per_month) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb7-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(variant, engine, drive) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb7-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">n =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">n</span>()) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb7-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pivot_wider</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">names_from=</span>drive, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_from=</span>n, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_fill=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb7-6">  knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">variant</th>
<th style="text-align: left;">engine</th>
<th style="text-align: right;">2WD</th>
<th style="text-align: right;">AWD</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">SE-L</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">32</td>
<td style="text-align: right;">0</td>
</tr>
<tr class="even">
<td style="text-align: left;">SE-L Lux</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">48</td>
<td style="text-align: right;">0</td>
</tr>
<tr class="odd">
<td style="text-align: left;">SE-L Lux</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">27</td>
<td style="text-align: right;">0</td>
</tr>
<tr class="even">
<td style="text-align: left;">Sport Lux</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">88</td>
<td style="text-align: right;">0</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Sport Lux</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">89</td>
<td style="text-align: right;">0</td>
</tr>
<tr class="even">
<td style="text-align: left;">GT Sport</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">27</td>
<td style="text-align: right;">0</td>
</tr>
<tr class="odd">
<td style="text-align: left;">GT Sport</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">60</td>
<td style="text-align: right;">12</td>
</tr>
<tr class="even">
<td style="text-align: left;">GT Sport Tech</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">13</td>
<td style="text-align: right;">0</td>
</tr>
<tr class="odd">
<td style="text-align: left;">GT Sport Tech</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">82</td>
<td style="text-align: right;">13</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>If none of the arrangements looks good then revert to using the one-dimensional listing format with one or more summarised values that we started this notebook with.</p>
<p>A simple form of table caption can be provided in the call to <code>knitr::kable</code>.</p>
<div class="cell" data-hash="tabulation_cache/html/unnamed-chunk-8_0f48087399ef5ebb9060ee3f5828c200">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb8-1">cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb8-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(variant, engine, drive, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm=</span>depreciation_per_month) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb8-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(engine, drive) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb8-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">n =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">n</span>()) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb8-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pivot_wider</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">names_from=</span>drive, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_from=</span>n, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_fill=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb8-6">  knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">caption=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"A Count of Drive by Engine"</span>)</span></code></pre></div></div>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<caption>A Count of Drive by Engine</caption>
<thead>
<tr class="header">
<th style="text-align: left;">engine</th>
<th style="text-align: right;">2WD</th>
<th style="text-align: right;">AWD</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">208</td>
<td style="text-align: right;">0</td>
</tr>
<tr class="even">
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">258</td>
<td style="text-align: right;">25</td>
</tr>
</tbody>
</table>
</div>
</div>
<section id="row-totals---counts" class="level3">
<h3 class="anchored" data-anchor-id="row-totals---counts">Row Totals - Counts</h3>
<p>The mechanism can be extended to include row totals. The technique is to create a dataframe for the body of the table and another dataframe for the rowtotal and then to combine them with <code>bind_rows</code>.</p>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Note
</div>
</div>
<div class="callout-body-container callout-body">
<p>The terminology of row-totals and column-totals can be a little confusing. In this notebook a row-total is a row that appears beneath the main body of a table and a column-total is a column that appears to the right of the main body of a table.</p>
</div>
</div>
<div class="cell" data-hash="tabulation_cache/html/unnamed-chunk-9_8575527c2574ce8e0089d32de6d4295b">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb9-1">body <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb9-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(engine, drive) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb9-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(engine, drive) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb9-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">n =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">n</span>()) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb9-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pivot_wider</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">names_from=</span>drive, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_from=</span>n, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_fill=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>) </span>
<span id="cb9-6"></span>
<span id="cb9-7">rowtotals <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> body <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb9-8">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>() <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb9-9">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(</span>
<span id="cb9-10">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">across</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">where</span>(is.factor), <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Total"</span>),</span>
<span id="cb9-11">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">across</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">where</span>(is.numeric), sum)</span>
<span id="cb9-12">  ) </span>
<span id="cb9-13"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">bind_rows</span>(body, rowtotals) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb9-14">knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">engine</th>
<th style="text-align: right;">2WD</th>
<th style="text-align: right;">AWD</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">208</td>
<td style="text-align: right;">0</td>
</tr>
<tr class="even">
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">258</td>
<td style="text-align: right;">25</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Total</td>
<td style="text-align: right;">466</td>
<td style="text-align: right;">25</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>This is fine for simple additive counts, but for aggregates we need something better.</p>
</section>
<section id="row-totals---aggregates" class="level3">
<h3 class="anchored" data-anchor-id="row-totals---aggregates">Row Totals - Aggregates</h3>
<p>The problem with tables containing aggregates is that the aggregate of a column of aggregates is not the same as the aggregate you would obtain had you not previously grouped on the rows. An easy way to see this is to imagine dividing a collection of values up into two unequally sized groups. You can calculate the mean of each group but the mean of the whole collection is not equal in value to the mean of the two group means (it would be if the two groups were equally sized).</p>
<p>To calculate aggregates correctly for row totals we need to start with the cars dataframe and perform a different grouping for each kind of aggregate. Instead of grouping and summarising the body dataframe as we did above, we obtain row totals by grouping the cars dataframe across the table columns. This allows us to calculate an aggregate value for each group (table column) and our rowtotal is constructed as a single row dataframe that contains an aggregate value in each column and a blank value or text label in any column for which no aggregate can be calculated. We populate these blank or label columns using the <code>mutate</code> function.</p>
<div class="cell" data-hash="tabulation_cache/html/unnamed-chunk-10_960d501fc5d0463567e6ec6c6d57e2d1">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb10-1">body <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb10-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(engine, drive, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm=</span>depreciation_per_month) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb10-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(engine, drive) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb10-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(dpm, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">na.rm=</span>T)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb10-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pivot_wider</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">names_from=</span>drive, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_from=</span>dpm, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_fill=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>) </span>
<span id="cb10-6"></span>
<span id="cb10-7">rowtotals <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb10-8">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(drive, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm=</span>depreciation_per_month) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb10-9">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(drive) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb10-10">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(dpm, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">na.rm=</span>T)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb10-11">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pivot_wider</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">names_from=</span>drive, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_from=</span>dpm, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_fill=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb10-12">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">engine =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Median"</span>)</span>
<span id="cb10-13"></span>
<span id="cb10-14"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">bind_rows</span>(body, rowtotals) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb10-15">knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">engine</th>
<th style="text-align: right;">2WD</th>
<th style="text-align: right;">AWD</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">208</td>
<td style="text-align: right;">0</td>
</tr>
<tr class="even">
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">243</td>
<td style="text-align: right;">305</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Median</td>
<td style="text-align: right;">228</td>
<td style="text-align: right;">305</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>You will notice that the Aggregate value for the 2WD column is no longer the sum of the numbers above it - it is not even the mean or median of them. It is the median of the values of the dataframe 2WD column but not grouped by engine.</p>
</section>
<section id="row-column-and-grand-totals---aggregates" class="level3">
<h3 class="anchored" data-anchor-id="row-column-and-grand-totals---aggregates">Row, Column and Grand Totals - Aggregates</h3>
<p>To create a table with the full set of totals we reduce (group-by and summarise) the cars dataframe to build each of the totals, so that we handle aggregates correctly, and then we stitch them together into a table.</p>
<div class="cell" data-hash="tabulation_cache/html/unnamed-chunk-11_de346ebf1b1e00d2b80012519a8e03e4">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb11-1">body <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb11-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(engine, drive, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm=</span>depreciation_per_month) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb11-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(engine, drive) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb11-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(dpm, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">na.rm=</span>T)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb11-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pivot_wider</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">names_from=</span>drive, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_from=</span>dpm, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_fill=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>) </span>
<span id="cb11-6"></span>
<span id="cb11-7">rowtotals <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb11-8">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(drive, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm=</span>depreciation_per_month) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb11-9">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(drive) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb11-10">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(dpm, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">na.rm=</span>T)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb11-11">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pivot_wider</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">names_from=</span>drive, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_from=</span>dpm, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_fill=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb11-12">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">engine =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Median"</span>)</span>
<span id="cb11-13"></span>
<span id="cb11-14">coltotals <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb11-15">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(engine, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm=</span>depreciation_per_month) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb11-16">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(engine) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb11-17">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">Median =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(dpm, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">na.rm=</span>T))</span>
<span id="cb11-18"></span>
<span id="cb11-19">grandtotal <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb11-20">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm=</span>depreciation_per_month) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb11-21">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">engine=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Median"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">Median =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(dpm, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">na.rm=</span>T)) </span>
<span id="cb11-22"></span>
<span id="cb11-23">all <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">inner_join</span>(</span>
<span id="cb11-24">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">bind_rows</span>(body, rowtotals),</span>
<span id="cb11-25">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">bind_rows</span>(coltotals, grandtotal)</span>
<span id="cb11-26">)</span>
<span id="cb11-27">knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(all, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">engine</th>
<th style="text-align: right;">2WD</th>
<th style="text-align: right;">AWD</th>
<th style="text-align: right;">Median</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">208</td>
<td style="text-align: right;">0</td>
<td style="text-align: right;">208</td>
</tr>
<tr class="even">
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">243</td>
<td style="text-align: right;">305</td>
<td style="text-align: right;">244</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Median</td>
<td style="text-align: right;">228</td>
<td style="text-align: right;">305</td>
<td style="text-align: right;">234</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>This seems like quite a lot of work for a 3-row by 4-column table but it is quite flexible. If you can see from the above code fragment how the table is constructed there is no need to read the next section which simply shows a breakdown of each stage of the table construction.</p>
</section>
<section id="assembly-of-the-complete-table---bit-by-bit" class="level3">
<h3 class="anchored" data-anchor-id="assembly-of-the-complete-table---bit-by-bit">Assembly of the Complete Table - Bit by Bit</h3>
<p>We begin by creating the body of the table.</p>
<div class="cell" data-hash="tabulation_cache/html/unnamed-chunk-12_9cef4c493bfa64212c9fd98c1ac8192f">
<details class="code-fold">
<summary>Show the code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb12-1">body <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb12-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(engine, drive, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm=</span>depreciation_per_month) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb12-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(engine, drive) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb12-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(dpm, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">na.rm=</span>T)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb12-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pivot_wider</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">names_from=</span>drive, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_from=</span>dpm, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_fill=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>) </span>
<span id="cb12-6">knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(body, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
</details>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">engine</th>
<th style="text-align: right;">2WD</th>
<th style="text-align: right;">AWD</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">208</td>
<td style="text-align: right;">0</td>
</tr>
<tr class="even">
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">243</td>
<td style="text-align: right;">305</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>Then we create the row totals as a single row dataframe with a value for each table column. It does not matter that the engine column appears as the last column in the dataframe.</p>
<div class="cell" data-hash="tabulation_cache/html/unnamed-chunk-13_bed53a42b838b5440306d5ffe9d2e9dc">
<details class="code-fold">
<summary>Show the code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb13-1">rowtotals <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb13-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(drive, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm=</span>depreciation_per_month) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb13-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(drive) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb13-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(dpm, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">na.rm=</span>T)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb13-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pivot_wider</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">names_from=</span>drive, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_from=</span>dpm, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">values_fill=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb13-6">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">engine =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Median"</span>)</span>
<span id="cb13-7">knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(rowtotals, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
</details>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: right;">2WD</th>
<th style="text-align: right;">AWD</th>
<th style="text-align: left;">engine</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: right;">228</td>
<td style="text-align: right;">305</td>
<td style="text-align: left;">Median</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>We create the column totals as a dataframe with a row for each row in the main body of the table. Each row contains a field (or fields) that allows us to find the table row with which to associate it, and a value to use as the column total.</p>
<div class="cell" data-hash="tabulation_cache/html/unnamed-chunk-14_b572f56114b22300d48f1657599570df">
<details class="code-fold">
<summary>Show the code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb14-1">coltotals <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb14-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(engine, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm=</span>depreciation_per_month) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb14-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(engine) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb14-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">Median =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(dpm, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">na.rm=</span>T))</span>
<span id="cb14-5">knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(coltotals, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
</details>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">engine</th>
<th style="text-align: right;">Median</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">208</td>
</tr>
<tr class="even">
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">244</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>The grand total is a dataframe with a single row and a column that will link it to the rowtotal row of the table and a value to use as the grand total.</p>
<div class="cell" data-hash="tabulation_cache/html/unnamed-chunk-15_d72442f847e4d7fd78287b94fe868fcc">
<details class="code-fold">
<summary>Show the code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb15" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb15-1">grandtotal <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb15-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm=</span>depreciation_per_month) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb15-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">engine=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Median"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">Median =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(dpm, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">na.rm=</span>T)) </span>
<span id="cb15-4">knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(grandtotal, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
</details>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">engine</th>
<th style="text-align: right;">Median</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">Median</td>
<td style="text-align: right;">234</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>We bind the body and the rowtotals together into a single dataframe. The rowtotals appear as the final row of the dataframe. The values in the engine column are going to be used to position the column totals and the grand total correctly later.</p>
<div class="cell" data-hash="tabulation_cache/html/unnamed-chunk-16_0c7af2323e9f2f1e6413aa3e4c83f595">
<details class="code-fold">
<summary>Show the code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb16" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb16-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">bind_rows</span>(body, rowtotals) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb16-2">knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
</details>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">engine</th>
<th style="text-align: right;">2WD</th>
<th style="text-align: right;">AWD</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">208</td>
<td style="text-align: right;">0</td>
</tr>
<tr class="even">
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">243</td>
<td style="text-align: right;">305</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Median</td>
<td style="text-align: right;">228</td>
<td style="text-align: right;">305</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>So we now have the main body of the table and the row totals in a single dataframe. Next we need to create a similar dataframe containing the column totals and the grand total.</p>
<p>We bind the coltotals and the grandtotal together into a single dataframe.</p>
<div class="cell" data-hash="tabulation_cache/html/unnamed-chunk-17_a837ffc366edbc85cc5bca763b80046c">
<details class="code-fold">
<summary>Show the code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb17" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb17-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">bind_rows</span>(coltotals, grandtotal) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb17-2">knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
</details>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">engine</th>
<th style="text-align: right;">Median</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">208</td>
</tr>
<tr class="even">
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">244</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Median</td>
<td style="text-align: right;">234</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>Finally, we glue the two dataframes together by joining them on their common <code>engine</code> column. This is the column that contains values of the row dimension of the table.</p>
<p>The join ensures that the columns from the body and rowtotals appear before the columns from the coltotals and grandtotal. So the effect that we get is that the Median column appears as the last table column.</p>
<div class="cell" data-hash="tabulation_cache/html/unnamed-chunk-18_4b109191249bc3a9856e7fd7ab117288">
<details class="code-fold">
<summary>Show the code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb18" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb18-1">all <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">inner_join</span>(</span>
<span id="cb18-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">bind_rows</span>(body, rowtotals),</span>
<span id="cb18-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">bind_rows</span>(coltotals, grandtotal)</span>
<span id="cb18-4">)</span>
<span id="cb18-5">knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(all, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
</details>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">engine</th>
<th style="text-align: right;">2WD</th>
<th style="text-align: right;">AWD</th>
<th style="text-align: right;">Median</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">208</td>
<td style="text-align: right;">0</td>
<td style="text-align: right;">208</td>
</tr>
<tr class="even">
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">243</td>
<td style="text-align: right;">305</td>
<td style="text-align: right;">244</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Median</td>
<td style="text-align: right;">228</td>
<td style="text-align: right;">305</td>
<td style="text-align: right;">234</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>And that is our complete table.</p>
<p>The deconstruction makes is sound like more work than it really is.</p>


</section>

 ]]></description>
  <category>R</category>
  <category>Car Price</category>
  <category>Mazda CX-30</category>
  <guid>https://www.oldgang.net/notebooks/posts/car_prices/04.tabulation/tabulation.html</guid>
  <pubDate>Fri, 14 Apr 2023 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Mazda CX-30 Price Data - Modelling</title>
  <dc:creator>John Bates</dc:creator>
  <link>https://www.oldgang.net/notebooks/posts/car_prices/03.modelling/modelling.html</link>
  <description><![CDATA[ 




<p>Given the cleaned dataset that we created in the companion notebook <a href="../../../../notebooks/posts/car_prices/01.preparation/preparation.html">Car Price Data - Preparation</a> we now want to attempt to obtain some numerical estimates of how different variables affect the monthly car price depreciation. As in the previous notebook we will be using the <code>tidyverse</code> packages.</p>
<p>We start by reading in the cars tibble that we created and saved.</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-1_09b3730450453bba4a99a8e6b364167f">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb1-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(tidyverse)</span>
<span id="cb1-2">cars <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">readRDS</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"../01.preparation/mazda.rds"</span>)</span></code></pre></div></div>
</div>
<p>We restrict its content to used “Used” cars. And we restrict its content to cars for which we have a value for depreciation_per_month.</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-2_3e3ccd8a3393bf5f68469a622801d40f">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb2-1">cars <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb2-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(new_used <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Used"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb2-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">is.na</span>(depreciation_per_month))</span></code></pre></div></div>
</div>
<p>We ended the visualisation notebook with a table of monthly median depreciation values for each combination of variant, engine and drive.</p>
<p>These are ordered in ascending order of the median depreciation per month.</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-3_0a040be63a595ca5fea27bcaf55fde0b">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb3-1">cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb3-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(depreciation_per_month, variant, engine, drive) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb3-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(variant, engine, drive) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb3-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">n=</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">n</span>(), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">median_dpm =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(depreciation_per_month)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb3-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">arrange</span>(median_dpm) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb3-6">  knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">variant</th>
<th style="text-align: left;">engine</th>
<th style="text-align: left;">drive</th>
<th style="text-align: right;">n</th>
<th style="text-align: right;">median_dpm</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">SE-L Lux</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: left;">2WD</td>
<td style="text-align: right;">48</td>
<td style="text-align: right;">186</td>
</tr>
<tr class="even">
<td style="text-align: left;">SE-L</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: left;">2WD</td>
<td style="text-align: right;">32</td>
<td style="text-align: right;">195</td>
</tr>
<tr class="odd">
<td style="text-align: left;">SE-L Lux</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: left;">2WD</td>
<td style="text-align: right;">27</td>
<td style="text-align: right;">218</td>
</tr>
<tr class="even">
<td style="text-align: left;">Sport Lux</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: left;">2WD</td>
<td style="text-align: right;">88</td>
<td style="text-align: right;">223</td>
</tr>
<tr class="odd">
<td style="text-align: left;">GT Sport</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: left;">2WD</td>
<td style="text-align: right;">27</td>
<td style="text-align: right;">233</td>
</tr>
<tr class="even">
<td style="text-align: left;">Sport Lux</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: left;">2WD</td>
<td style="text-align: right;">89</td>
<td style="text-align: right;">241</td>
</tr>
<tr class="odd">
<td style="text-align: left;">GT Sport Tech</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: left;">2WD</td>
<td style="text-align: right;">13</td>
<td style="text-align: right;">252</td>
</tr>
<tr class="even">
<td style="text-align: left;">GT Sport</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: left;">2WD</td>
<td style="text-align: right;">60</td>
<td style="text-align: right;">253</td>
</tr>
<tr class="odd">
<td style="text-align: left;">GT Sport Tech</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: left;">2WD</td>
<td style="text-align: right;">82</td>
<td style="text-align: right;">285</td>
</tr>
<tr class="even">
<td style="text-align: left;">GT Sport</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: left;">AWD</td>
<td style="text-align: right;">12</td>
<td style="text-align: right;">304</td>
</tr>
<tr class="odd">
<td style="text-align: left;">GT Sport Tech</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: left;">AWD</td>
<td style="text-align: right;">13</td>
<td style="text-align: right;">306</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>The difference in depreciation between the 2WD SE-L Lux with the e-Skyactiv G engine and the top of the range AWD GT Sport Tech with the e-Skyactiv X engine is about £120 per month. So we can see that these variables clearly have an influence on the depreciation but we would like to know just how much that influence it.</p>
<p>One method available to us is to perform a linear regression of our independent variables (variant, engine, drive, age_in_months and miles_per_month) on our dependent variable depreciation_per_month.</p>
<p>There are several assumptions made when using linear regression:</p>
<ol type="1">
<li><strong>The independent variables are truly independent of each other</strong>: This is a reasonable assumption here, especially after we converted depreciation to depreciation_per_month and miles to miles_per_month thereby removing a dependency on age_in_months.</li>
<li><strong>There are no outliers</strong>: We will ensure that below.</li>
<li><strong>The variables are normally distributed</strong>: This one is a little more tricky. Some are, some not so much.</li>
<li><strong>There is a linear relationship between the independent variables and the dependent variable</strong>: An assumption that we will make based on the scatter-plots of the previous notebook.</li>
</ol>
<p>A <code>pairs.panels</code> plot from the <code>psych</code> library confirms that the correlations between the independent variables are low.</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-4_806dfd9ac416fae90fcd7e868d717fdd">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb4-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"psych"</span>)</span>
<span id="cb4-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pairs.panels</span>(</span>
<span id="cb4-3">  cars[<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>( <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"variant"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"drive"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"engine"</span>,<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"age_in_months"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"miles_per_month"</span>)],</span>
<span id="cb4-4">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">cor=</span>T</span>
<span id="cb4-5">)</span></code></pre></div></div>
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://www.oldgang.net/notebooks/posts/car_prices/03.modelling/modelling_files/figure-html/unnamed-chunk-4-1.png" class="img-fluid figure-img" width="672"></p>
</figure>
</div>
</div>
</div>
<p>We should also consider removing outliers from our analysis. The outliers are the observations that lie beyond the extremes of the whiskers in a box and whiskers plot. That is, those observations that are more than 1.5 times the interquartile range above or below the 75% and 25% quartiles.</p>
<p>We can see the outliers on the boxplot.</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-5_19781624f026b9f76e592f8469b97602">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb5-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(</span>
<span id="cb5-2">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> cars,</span>
<span id="cb5-3">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">mapping =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> depreciation_per_month)</span>
<span id="cb5-4">) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_boxplot</span>() </span></code></pre></div></div>
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://www.oldgang.net/notebooks/posts/car_prices/03.modelling/modelling_files/figure-html/unnamed-chunk-5-1.png" class="img-fluid figure-img" width="672"></p>
</figure>
</div>
</div>
</div>
<p>These can be captured and removed by calculating the interquartile range and the 25% and 75% quantiles.</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-6_e4efd011feaef5affeea6768d96c65d1">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb6-1">iqr <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">IQR</span>(cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>depreciation_per_month)</span>
<span id="cb6-2"></span>
<span id="cb6-3">q25 <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">quantile</span>(cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>depreciation_per_month, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.25</span>)</span>
<span id="cb6-4">q75 <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">quantile</span>(cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>depreciation_per_month, <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.75</span>)</span>
<span id="cb6-5">lower <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> q25 <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.5</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>iqr</span>
<span id="cb6-6">upper <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> q75 <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.5</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span>iqr</span>
<span id="cb6-7"></span>
<span id="cb6-8">outliers <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb6-9">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(</span>
<span id="cb6-10">      depreciation_per_month <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> upper</span>
<span id="cb6-11">    <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> depreciation_per_month <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> lower</span>
<span id="cb6-12">  )</span></code></pre></div></div>
</div>
<p>We can examine the outliers by variant, engine and drive and then calculate their median depreciation_per_month (dpm), depreciation (d) and age_in_months (a).</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-7_d8dcc2ff621ef1c1f48a07ff0bdef438">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb7-1">outliers <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb7-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(</span>
<span id="cb7-3">    depreciation_per_month, variant, engine, drive,</span>
<span id="cb7-4">    depreciation, age_in_months</span>
<span id="cb7-5">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb7-6">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(variant, engine, drive) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb7-7">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">n=</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">n</span>(),</span>
<span id="cb7-8">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(depreciation_per_month, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">na.rm=</span>T),</span>
<span id="cb7-9">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">d=</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(depreciation, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">na.rm=</span>T),</span>
<span id="cb7-10">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">a=</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(age_in_months, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">na.rm=</span>T)</span>
<span id="cb7-11">  ) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb7-12">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">arrange</span>(dpm) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb7-13">  knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">variant</th>
<th style="text-align: left;">engine</th>
<th style="text-align: left;">drive</th>
<th style="text-align: right;">n</th>
<th style="text-align: right;">dpm</th>
<th style="text-align: right;">d</th>
<th style="text-align: right;">a</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">Sport Lux</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: left;">2WD</td>
<td style="text-align: right;">2</td>
<td style="text-align: right;">249</td>
<td style="text-align: right;">4900</td>
<td style="text-align: right;">12</td>
</tr>
<tr class="even">
<td style="text-align: left;">GT Sport</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: left;">2WD</td>
<td style="text-align: right;">5</td>
<td style="text-align: right;">407</td>
<td style="text-align: right;">3665</td>
<td style="text-align: right;">6</td>
</tr>
<tr class="odd">
<td style="text-align: left;">GT Sport Tech</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: left;">AWD</td>
<td style="text-align: right;">1</td>
<td style="text-align: right;">407</td>
<td style="text-align: right;">8556</td>
<td style="text-align: right;">18</td>
</tr>
<tr class="even">
<td style="text-align: left;">GT Sport</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: left;">2WD</td>
<td style="text-align: right;">1</td>
<td style="text-align: right;">412</td>
<td style="text-align: right;">3705</td>
<td style="text-align: right;">6</td>
</tr>
<tr class="odd">
<td style="text-align: left;">GT Sport Tech</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: left;">2WD</td>
<td style="text-align: right;">2</td>
<td style="text-align: right;">423</td>
<td style="text-align: right;">3810</td>
<td style="text-align: right;">6</td>
</tr>
<tr class="even">
<td style="text-align: left;">Sport Lux</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: left;">2WD</td>
<td style="text-align: right;">1</td>
<td style="text-align: right;">446</td>
<td style="text-align: right;">4010</td>
<td style="text-align: right;">6</td>
</tr>
<tr class="odd">
<td style="text-align: left;">GT Sport</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: left;">AWD</td>
<td style="text-align: right;">1</td>
<td style="text-align: right;">480</td>
<td style="text-align: right;">7205</td>
<td style="text-align: right;">12</td>
</tr>
<tr class="even">
<td style="text-align: left;">SE-L Lux</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: left;">2WD</td>
<td style="text-align: right;">2</td>
<td style="text-align: right;">518</td>
<td style="text-align: right;">7448</td>
<td style="text-align: right;">12</td>
</tr>
<tr class="odd">
<td style="text-align: left;">GT Sport Tech</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: left;">2WD</td>
<td style="text-align: right;">2</td>
<td style="text-align: right;">599</td>
<td style="text-align: right;">3568</td>
<td style="text-align: right;">3</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>We notice that the outliers look to be mainly from the very expensive combinations of variant and engine and so it may really be that they were highly depreciated vehicles. We could choose to leave these outliers in for the analysis and treat them as valid observations. But given that they are quite small in number we will remove them.</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-8_498524a3db78110b301c74821f352e77">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb8-1">cars <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb8-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(</span>
<span id="cb8-3">      depreciation_per_month <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> upper</span>
<span id="cb8-4">    <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> depreciation_per_month <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> lower</span>
<span id="cb8-5">  )</span></code></pre></div></div>
</div>
<section id="linear-regression" class="level3">
<h3 class="anchored" data-anchor-id="linear-regression">Linear Regression</h3>
<p>To estimate the numeric effect of each of our independent variables on the value of the dependent <code>depreciation_per_month</code> variable we can perform a linear regression on the data.</p>
<p>A linear regression will fit a straight line through the data of the form:</p>
<p><img src="https://latex.codecogs.com/png.latex?%0Adepreciation%5C_per%5C_month%20=%20%5Calpha%20+%20%5Cbeta_1%20*%20variant%20+%20%5Cbeta_2%20*%20engine%20+%20%5Cbeta_3%20*%20drive%20...%0A"></p>
<p>We will be interested in the value of <img src="https://latex.codecogs.com/png.latex?%5Calpha">, and the accompanying <img src="https://latex.codecogs.com/png.latex?%5Cbeta"> values. The constant value <img src="https://latex.codecogs.com/png.latex?%5Calpha"> will give us the base monthly depreciation and the the <img src="https://latex.codecogs.com/png.latex?%5Cbeta">s will give us the amount by which the predicted monthly depreciation will be increased (or decreased) when a vehicle has the associated variant, engine size or drive. Or in the case of the continuous independent variables, how much the predicted monthly depreciation will increase with each month of age or mile of travel of the vehicle.</p>
<p>To handle the independent variables that are factors, the model will employ <em>dummy coding</em> to convert each value of the factor into a numeric variable that takes on the value zero or one according as the observation takes on that value of the factor. When performing this conversion the first level of the factor is left out as it represents the situation when all of the other dummy coded factor values for that factor take on the value zero. This will be a little clearer when we look at the results of the regression.</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-9_26158b897a1907a354cec462f3c8d861">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb9-1">model.lm <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">lm</span>(</span>
<span id="cb9-2">  depreciation_per_month <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span></span>
<span id="cb9-3">    variant<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>engine<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>drive<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>age_in_months<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>miles_per_month,</span>
<span id="cb9-4">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data=</span>cars</span>
<span id="cb9-5">)</span>
<span id="cb9-6"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summary</span>(model.lm)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>
Call:
lm(formula = depreciation_per_month ~ variant + engine + drive + 
    age_in_months + miles_per_month, data = cars)

Residuals:
     Min       1Q   Median       3Q      Max 
-136.530  -14.875    0.466   19.318  124.951 

Coefficients:
                       Estimate Std. Error t value Pr(&gt;|t|)    
(Intercept)          236.784458   6.777371  34.938  &lt; 2e-16 ***
variantSE-L Lux       36.073971   6.607608   5.459 7.79e-08 ***
variantSport Lux      38.310408   6.008123   6.376 4.38e-10 ***
variantGT Sport       60.552317   6.605046   9.168  &lt; 2e-16 ***
variantGT Sport Tech  78.190497   6.737117  11.606  &lt; 2e-16 ***
enginee-Skyactiv X     1.360104   3.230797   0.421    0.674    
driveAWD              47.097788   6.695771   7.034 7.22e-12 ***
age_in_months         -3.312248   0.146638 -22.588  &lt; 2e-16 ***
miles_per_month        0.093089   0.006535  14.244  &lt; 2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 29.95 on 465 degrees of freedom
Multiple R-squared:  0.6921,    Adjusted R-squared:  0.6868 
F-statistic: 130.6 on 8 and 465 DF,  p-value: &lt; 2.2e-16</code></pre>
</div>
</div>
<p>The residuals in the output are an indication of how well (or badly) our model fits the observed values of depreciation_per_month. The first thing to notice is that the maximum and minimum values of the residuals are £124 and -£136 respectively. These are the worst cases. The 50% of observations that fall between the 1Q and 3Q values have residuals that range between -£14 and £19. That seems like a very comfortable range.</p>
<p>Before examining the fitted values we need to look at the goodness of fit. The <em>Adjusted R-squared</em> value of 0.6868 is good. This value gives us an indication of how well our model explains the variation in monthly depreciation - in this case approximately 68%.</p>
<p>We also see that the three stars against each of the independent variables (except for engine) tell us that it is extremely unlikely that they do not influence the value of our modelled dependent variable, depreciation_per_month.</p>
<p>We can plot the residuals against the fitted values of the model:</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-10_5b49dbd347deb6b28c1f0e3539fc5c26">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb11-1">predicted <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">predict</span>(model.lm)</span>
<span id="cb11-2">residuals <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">residuals</span>(model.lm)</span>
<span id="cb11-3"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(</span>
<span id="cb11-4">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> cars,</span>
<span id="cb11-5">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> predicted, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> residuals)</span>
<span id="cb11-6">) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_point</span>()</span></code></pre></div></div>
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://www.oldgang.net/notebooks/posts/car_prices/03.modelling/modelling_files/figure-html/unnamed-chunk-10-1.png" class="img-fluid figure-img" width="672"></p>
</figure>
</div>
</div>
</div>
<p>This seems like a reasonable spread, perhaps slightly wider towards the higher end of the predicted values but good enough. Given that we are happy with the fit of the model we can now look at the values of the various fitted coefficients.</p>
<p>Before we can do that though we need to understand how the non-numeric (nominal) dependent variables in our model are handled by the regression. We can see that:</p>
<ul>
<li>For our 5 level <code>variant</code> variable the model contains 4 parameters: variantSE-L Lux, variantSport Lux, variantGT Sport, variantGT Sport Tech.</li>
<li>For our 2 level <code>engine</code> variable the model contains a single parameter: enginee-Skyactiv X.</li>
<li>For our 2 level <code>drive</code> variable the model contains a single parameter: driveAWD.</li>
<li>For our numeric <code>age_in_months</code> variable the model contains a single parameter: age_in_months.</li>
<li>For our numeric <code>miles_per_month</code> variable the model contains a single parameter: miles_per_month.</li>
</ul>
<p>The key thing to note is that each non-numeric variable (a factor in our dataset) is represented in the model by (n-1) parameters where n is the number of levels of the factor that represents the nominal variable. The regression ensures that the effect of the first of the factor levels is incorporated into the value of the estimated intercept. To see the effect of having one of the other factor levels in an observation we need to add its associated coefficient to the value of the intercept.</p>
<p>For example, to represent the <code>drive</code> factor our model has a parameter driveAWD with a coefficient of (roughly) 47. This tells us that, in general, a vehicle with AWD will depreciate at £47 per month more than a vehicle with 2WD. If we plug the estimated intercept value and the rounded coefficients for the various model parameters into our model equation it looks like this:</p>
<pre><code>  depreciation_per_month = 237
    + 36 * variantSE-L Lux 
    + 38 * variantSport Lux
    + 61 * variantGT Sport
    + 70 * variantGT Sport Tech
    + 47 * driveAWD
    - 3 * age_in_months
    + 0.09 * miles_per_month</code></pre>
<p>We have omitted the engine parameter from this model because the regression analysis determined that it has an insignificant effect on the monthly depreciation.</p>
<p>The intercept value of £237 can be considered to be the estimated monthly depreciation of a vehicle with variant=SE-L, drive=2WD, age_in_months=0 and miles_per_month=0.</p>
<p>Were we to replace our variant SE-L with a variant of GT Sport then we should expect our monthly depreciation to increase by £61. If we then further opted for 4WD we could add another £47 onto the estimated monthly depreciation.</p>
<p>Similarly for the numeric parameters, if we were to consider the same specification at 12 months old we would subtract 12 * £3 = £36 from the estimated monthly depreciation. And 1,000 mile per month of travel would add £90 onto the estimated monthly depreciation.</p>
<p>So the regression gives us a very understandable explanation of how much each of the independent variables affects the value of the monthly depreciation.</p>
</section>
<section id="regression-trees" class="level3">
<h3 class="anchored" data-anchor-id="regression-trees">Regression Trees</h3>
<p>An alternative to using linear regression to model our data is to use regression trees. A regression tree model is built by splitting the set of observations into two partitions in such a way as to maximise the reduction in variation between the observations that lie within each partition. This requires both a choice of feature to split on and then a value with which to partition the data on that feature.</p>
<p>For example, if the miles_per_month feature is chosen as the one that can maximise the reduction in variation, it might then be determined to partition the data into two sets: one whose miles_per_month value was &gt;1000 and one whose miles_per_month value was &lt;= 1000.</p>
<p>This gives us two nodes of a tree. Then the procedure is repeated on the data in each node, giving us four nodes, and so on until there is no significant reduction to be obtained by splitting further.</p>
<p>Once the tree has been constructed by repeating the above process we have:</p>
<ol type="1">
<li>A set of rules that result in a path to each of the leaf nodes.</li>
<li>A set of homogeneous data in each node from which a mean value of the dependent variable <code>depreciation_per_month</code> can be determined.</li>
</ol>
<p>For a new observation we can follow the set of rules until we arrive at a leaf node and then we can use the mean value of monthly depreciation of observations in that node as our estimate of the monthly depreciation of the new observation.</p>
<p>To build a regression tree we use the “rpart” package and its associated plotting package.</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-11_b1b2f15d4bbdaa532678eea0b4c14099">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb13-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(rpart)</span>
<span id="cb13-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(rpart.plot)</span></code></pre></div></div>
</div>
<p>We will build a regression tree model using the same variables that we used for the linear regression model.</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-12_675e5ff1e8b4b34e5c04d7ae8794c914">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb14-1">model.rt <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rpart</span>(</span>
<span id="cb14-2">  depreciation_per_month <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span></span>
<span id="cb14-3">    variant<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>drive<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>engine<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>age_in_months<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>miles_per_month,</span>
<span id="cb14-4">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> cars</span>
<span id="cb14-5">)</span></code></pre></div></div>
</div>
<p>A good visual representation of the regression tree can be obtains by using <code>rpart.plot</code>.</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-13_ca9403f747dc1a2d51d96a6d7102541d">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb15" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb15-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rpart.plot</span>(model.rt)</span></code></pre></div></div>
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://www.oldgang.net/notebooks/posts/car_prices/03.modelling/modelling_files/figure-html/unnamed-chunk-13-1.png" class="img-fluid figure-img" width="672"></p>
</figure>
</div>
</div>
</div>
<p>We can see that the first variable that was split was <code>age_in_months</code> and that the resulting tree has five levels and terminates in 15 leaf nodes. The values within each node are the mean depreciation_per_month of the observations that fall into that node and the percentage of the observations that reach that point.</p>
<p>Because <code>age_in_months</code> was used first in the tree it is the single most important predictor of the monthly depreciation of a vehicle. The regression model divides the observations on <code>age_in_months &gt;= 21</code>, placing all observations for which this is true in the node on the left-hand-side of the split and all other observations in the node on the right-hand-side.</p>
<p>We can repeat this process right the way down the tree. If we consider the observations for which <code>age_in_months</code> is not greater than 21 (i.e.&nbsp;relatively new vehicles) then the next best predictor of monthly depreciation is <code>variant</code>. This node tells us that for the cheapest variants (SE-L, SE-L Lux and Sport Lux) the next best predictor is <code>miles_per_month</code> otherwise the model takes us straight to a leaf node with an estimate of monthly depreciation of £307.</p>
<p>We can get a feel for how good our model is by calculating the mean absolute error.</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-14_fc6d23cfd6459a50d9fe6b1916903069">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb16" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb16-1">MAE <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(actual, predicted) { <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mean</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">abs</span>(actual <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> predicted))}</span></code></pre></div></div>
</div>
<p>Normally we would have divided our observations up into a training set and a testing set to perform this operation but here we will use mean absolute error to get a feel for how closely this model can predict our observed monthly depreciation.</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-15_1d3186a77810f8701c4cd5e5fca6aa08">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb17" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb17-1">predicted <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">predict</span>(model.rt, cars)</span>
<span id="cb17-2">actual <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>depreciation_per_month</span>
<span id="cb17-3"></span>
<span id="cb17-4"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">print</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">MAE</span>(actual, predicted))</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>[1] 22.85299</code></pre>
</div>
</div>
<p>So, on average, our model predicts the value of the monthly depreciation to within £23 of the observed depreciation. We could think of that as a measure of what we have lost by summarising the data into a structured and explainable model.</p>
<p>Let us look at what we would have obtained had we trained our model on a proportion of the data and then used the remaining observations to test its predictive accuracy.</p>
<p>We use <code>set.seed</code> to ensure that our results are reproducible. We take a random selection of 90% of our observations for the training set and use the remaining 10% to test the resulting model.</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-16_7d3bbb9b81666f0d96c3c6945a435b4a">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb19" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb19-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">set.seed</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">15151</span>)</span>
<span id="cb19-2">n <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> (cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">count</span>())[[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>]]</span>
<span id="cb19-3">cars_rand <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars[<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">order</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">runif</span>(n)),]</span>
<span id="cb19-4">split <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">round</span>(n<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span><span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.9</span>, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span>
<span id="cb19-5"></span>
<span id="cb19-6">cars_train <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars_rand[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span>split, ]</span>
<span id="cb19-7">cars_test <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars_rand[(split<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span>n, ]</span>
<span id="cb19-8"></span>
<span id="cb19-9">model.rt.train <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rpart</span>(</span>
<span id="cb19-10">  depreciation_per_month <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> variant<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>drive<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>engine<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>age_in_months<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>miles_per_month,</span>
<span id="cb19-11">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> cars_train</span>
<span id="cb19-12">)</span></code></pre></div></div>
</div>
<p>We can plot the decision tree of the training model as we did for the model we obtained from the full set of data.</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-17_3386b1dbb9868e3d23335182a6f2706c">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb20" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb20-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rpart.plot</span>(model.rt.train)</span></code></pre></div></div>
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://www.oldgang.net/notebooks/posts/car_prices/03.modelling/modelling_files/figure-html/unnamed-chunk-17-1.png" class="img-fluid figure-img" width="672"></p>
</figure>
</div>
</div>
</div>
<p>Perhaps unsurprisingly, but somewhat reassuringly, the tree is almost identical to the previous one. The choice of variable to split on is unchanged at each point in the tree and the numerical splits differ very slightly in just two places. It feels as though the structure of the tree is quite stable.</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-18_f7ddb1979088f0e6810cccbb8d28dd4e">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb21" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb21-1">predicted <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">predict</span>(model.rt.train, cars_test)</span>
<span id="cb21-2">actual <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> cars_test<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>depreciation_per_month</span>
<span id="cb21-3"></span>
<span id="cb21-4"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">print</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">MAE</span>(actual, predicted))</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>[1] 25.53228</code></pre>
</div>
</div>
<p>As we would expect, the mean absolute error is slightly higher than the value that we obtained using the data that the model was trained on. Nevertheless this seems like a very small value for error in monthly depreciation, which suggests that our model is a good one.</p>
<p>We have seen how a regression tree can provide an alternative mechanism for understanding what drives monthly depreciation in our car dataset.</p>
</section>
<section id="linear-regression-vs-regression-tree" class="level3">
<h3 class="anchored" data-anchor-id="linear-regression-vs-regression-tree">Linear Regression vs Regression Tree</h3>
<p>We can compare the linear regression and the regression tree by training a new linear regression model on our training set and then calculating the mean absolute error of its predictions using the test data.</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-19_223862a7abc830901013cbc4e2df1ee0">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb23" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb23-1">model.lm.train <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">lm</span>(</span>
<span id="cb23-2">  depreciation_per_month <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> variant<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>engine<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>drive<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>age_in_months<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span>miles_per_month,</span>
<span id="cb23-3">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data=</span>cars_train</span>
<span id="cb23-4">)</span></code></pre></div></div>
</div>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-20_665cd7bc231786aca15d88b45e354309">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb24" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb24-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summary</span>(model.lm.train)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>
Call:
lm(formula = depreciation_per_month ~ variant + engine + drive + 
    age_in_months + miles_per_month, data = cars_train)

Residuals:
     Min       1Q   Median       3Q      Max 
-134.812  -14.294    0.223   19.508  124.575 

Coefficients:
                       Estimate Std. Error t value Pr(&gt;|t|)    
(Intercept)          236.182614   7.181542  32.887  &lt; 2e-16 ***
variantSE-L Lux       35.813388   7.004416   5.113 4.84e-07 ***
variantSport Lux      36.963980   6.406757   5.770 1.55e-08 ***
variantGT Sport       60.524787   7.045595   8.590  &lt; 2e-16 ***
variantGT Sport Tech  80.297976   7.209481  11.138  &lt; 2e-16 ***
enginee-Skyactiv X     1.417235   3.420915   0.414    0.679    
driveAWD              45.502400   6.776377   6.715 6.16e-11 ***
age_in_months         -3.298002   0.153850 -21.437  &lt; 2e-16 ***
miles_per_month        0.094333   0.006905  13.661  &lt; 2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 30 on 418 degrees of freedom
Multiple R-squared:  0.6999,    Adjusted R-squared:  0.6941 
F-statistic: 121.8 on 8 and 418 DF,  p-value: &lt; 2.2e-16</code></pre>
</div>
</div>
<p>A look at the model parameters confirms that it has hardly changed from the model that was fitted on the full set of data.</p>
<div class="cell" data-hash="modelling_cache/html/unnamed-chunk-21_6287fc759a391145d6569405b5e04f7a">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb26" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb26-1">predicted.rt <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">predict</span>(model.rt.train, cars_test)</span>
<span id="cb26-2">predicted.lm <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">predict</span>(model.lm.train, cars_test)</span>
<span id="cb26-3"></span>
<span id="cb26-4"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">print</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_glue</span>(</span>
<span id="cb26-5">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"MAE of regression tree:"</span>,</span>
<span id="cb26-6">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">round</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">MAE</span>(actual, predicted.rt),<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>))</span>
<span id="cb26-7">)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>MAE of regression tree:25.53</code></pre>
</div>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb28" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb28-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">print</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_glue</span>(</span>
<span id="cb28-2">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"MAE of linear regression:"</span>,</span>
<span id="cb28-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">round</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">MAE</span>(actual, predicted.lm),<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2</span>))</span>
<span id="cb28-4">)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>MAE of linear regression:23.38</code></pre>
</div>
</div>
<p>The errors are almost identical, with the linear regression slightly out performing the regression tree.</p>
<p>We now have two useful models of monthly depreciation that can be used to examine what drives depreciation on used Mazda CX-30 cars in the UK.</p>
<p>In the next notebook we will look at a mechanism for creating a simple two-dimensional table to display aggregated car price data.</p>
<p>Next: <a href="../../../../notebooks/posts/car_prices/04.tabulation/tabulation.html">Mazda CX-30 Price Data - Tabulation</a></p>


</section>

 ]]></description>
  <category>R</category>
  <category>Car Price</category>
  <category>Mazda CX-30</category>
  <guid>https://www.oldgang.net/notebooks/posts/car_prices/03.modelling/modelling.html</guid>
  <pubDate>Wed, 05 Apr 2023 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Mazda CX-30 Price Data - Visualisation</title>
  <dc:creator>John Bates</dc:creator>
  <link>https://www.oldgang.net/notebooks/posts/car_prices/02.visualisation/visualisation.html</link>
  <description><![CDATA[ 




<p>Given the cleaned dataset that we created in the companion notebook <a href="../../../../notebooks/posts/car_prices/01.preparation/preparation.html">Mazda 3 Price Data - Preparation</a> we can now start to look more closely at the factors that influence used car depreciation for our chosen model, the Mazda CX-30. As in the previous notebook we will be using the <code>tidyverse</code> packages.</p>
<p>We start by reading in the cars tibble that we created and saved.</p>
<div class="cell" data-hash="visualisation_cache/html/unnamed-chunk-1_992d9b2b41aa84c051d4bfb3850ce924">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb1-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(tidyverse)</span>
<span id="cb1-2">cars <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">readRDS</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"../01.preparation/mazda.rds"</span>)</span></code></pre></div></div>
</div>
<p>For the purposes of understanding depreciation we need to limit our data to used cars. That can be done very simply with the <code>filter</code> function of the tidyverse <code>dplyr</code> package.</p>
<div class="cell" data-hash="visualisation_cache/html/unnamed-chunk-2_99ac86da7d3dd0a896cc34775d19e9ac">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb2-1">cars <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb2-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(new_used <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Used"</span>)</span></code></pre></div></div>
</div>
<p>We can see that the data consists of several hundred rows on 14 columns. These represent several hundred observations on 14 variables - each row or observation is of a single vehicle and each observation has a value for each of the 14 variables.</p>
<p>There are some situations in which the value of a variable may be unknown for an observation. In such a case the value is represented with <code>NA</code> which we can think of as meaning <em>missing</em>. In most cases we will reject observations for which we have missing data.</p>
<div class="cell" data-hash="visualisation_cache/html/unnamed-chunk-3_c4ff87573e3f5bcd6529120441adac49">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb3-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str</span>(cars)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>tibble [493 × 14] (S3: tbl_df/tbl/data.frame)
 $ model                 : Factor w/ 1 level "Mazda CX-30": 1 1 1 1 1 1 1 1 1 1 ...
 $ variant               : Factor w/ 5 levels "SE-L","SE-L Lux",..: 5 1 2 5 5 1 5 4 4 5 ...
 $ drive                 : Factor w/ 2 levels "2WD","AWD": 1 1 1 1 1 1 1 1 2 1 ...
 $ engine                : Factor w/ 2 levels "e-Skyactiv G",..: 2 1 1 2 2 1 2 2 2 2 ...
 $ new_used              : Factor w/ 2 levels "Used","New": 1 1 1 1 1 1 1 1 1 1 ...
 $ miles                 : num [1:493] 6542 14814 17548 225 33258 ...
 $ miles_per_month       : num [1:493] 312 494 450 75 853 ...
 $ price                 : num [1:493] 24990 18785 21995 29994 21495 ...
 $ price_new             : num [1:493] 31815 24645 26145 31815 31815 ...
 $ depreciation          : num [1:493] 6825 5860 4150 1821 10320 ...
 $ depreciation_per_month: num [1:493] 325 195 106 607 265 ...
 $ fuel                  : Factor w/ 1 level "Petrol": 1 1 1 1 1 1 1 1 1 1 ...
 $ transmission          : Factor w/ 1 level "Manual": 1 1 1 1 1 1 1 1 1 1 ...
 $ age_in_months         : num [1:493] 18 24 36 0 36 24 30 6 30 24 ...</code></pre>
</div>
</div>
<p>A good place to start is to look at the relationships between the columns using a <code>pairs</code> plot. This plot uses the <code>pairs.panels</code> plot from the <code>psych</code> package to show, in addition to the normal pairs scatterplots, some information about the correlations between each displayed column.</p>
<p>The diagonal shows a histogram of the values of each variable. This gives us a visual indication of the distribution of values of that variable.</p>
<p>Above and below the diagonal are plots of each pairwise combinations of variable. The plots are overlaid by a linear regression line and a correlation ellipse. These indicate the general tendency of high values of one variable to be associated with high or low values of the other variable. A circular correlation ellipse indicates no such association.</p>
<div class="cell" data-hash="visualisation_cache/html/unnamed-chunk-4_9fac6d3ecfd8265a1e1a6b3c66070828">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb5-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"psych"</span>)</span>
<span id="cb5-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pairs.panels</span>(</span>
<span id="cb5-3">  cars[<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(</span>
<span id="cb5-4">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"variant"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"engine"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"age_in_months"</span>,</span>
<span id="cb5-5">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"miles"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"depreciation"</span></span>
<span id="cb5-6">  )],</span>
<span id="cb5-7">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">pch =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"."</span>,</span>
<span id="cb5-8">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">cor=</span>F,</span>
<span id="cb5-9">  <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">lm =</span> T,</span>
<span id="cb5-10">  )</span></code></pre></div></div>
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://www.oldgang.net/notebooks/posts/car_prices/02.visualisation/visualisation_files/figure-html/unnamed-chunk-4-1.png" class="img-fluid figure-img" width="672"></p>
</figure>
</div>
</div>
</div>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Note
</div>
</div>
<div class="callout-body-container callout-body">
<p>In addition to the list of variables to plot, the call to pairs.panels has three other parameters: <code>pch</code>, <code>cor</code> and <code>lm</code>.</p>
<p>Because there are so many data points to plot the <code>pch</code> parameter allows us to replace the default plot symbol, which is a bullet character (pch=20), with an alternative. Setting it to “.” is a special case which results in a plot very small rectangle used as the plot symbol.</p>
<p>Setting <code>cor</code> to false prevents the plot from displaying Pearson correlation coefficients. These are often useful but should really only be used when the distribution of the variables being compared is close to a normal distribution.</p>
<p>Setting <code>lm</code> to true gives us a linear regression line for each pair of variables in addition to the correlation ellipse.</p>
</div>
</div>
<p>The most obvious observation is that depreciation increases with both age of the vehicle and the number of miles that it has been driven. That is not surprising, but it is a reminder that depreciation is not really the variable that we are interested in. A more interesting value to measure would be depreciation over time.</p>
<p>Similarly, a measure of miles, being so highly correlated with age_in_months might be more usefully expressed as miles_per_month. Fortunately, we recognised that when preparing the data and we do have two variables, miles_per_month and depreciation_per_month, which attempt to correct the effect that age has on miles driven and depreciation.</p>
<p>If we we create the pairs plot using miles_per_month in place of miles and depreciation_per_month in place of depreciation we see a different picture.</p>
<div class="cell" data-hash="visualisation_cache/html/unnamed-chunk-5_841e4fa327cc7974be1704678b076902">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb6-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"psych"</span>)</span>
<span id="cb6-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">pairs.panels</span>(</span>
<span id="cb6-3">  cars[</span>
<span id="cb6-4">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"variant"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"engine"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"age_in_months"</span>,</span>
<span id="cb6-5">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"miles_per_month"</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"depreciation_per_month"</span>)],</span>
<span id="cb6-6">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">pch =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"."</span>,</span>
<span id="cb6-7">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">cor=</span>F,</span>
<span id="cb6-8">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">lm =</span> T</span>
<span id="cb6-9">  )</span></code></pre></div></div>
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://www.oldgang.net/notebooks/posts/car_prices/02.visualisation/visualisation_files/figure-html/unnamed-chunk-5-1.png" class="img-fluid figure-img" width="672"></p>
</figure>
</div>
</div>
</div>
<p>We see that a higher value of age_in_months is associated with a lower value of depreciation_per_month. That feels right, as a vehicle would be expected to lose value more quickly when it was newer. We also see that a higher value of miles_per_month is associated with a higher value of depreciation_per_month. Again, this is something that we might expect to see although it looks to be less highly correlated.</p>
<p>The plot of depreciation_per_month by variant suggests that there might be a high level of association between variant and depreciation_per_month but the fact that variant has only a small number of discrete values and the assumptions about variables being normally distributed mean that we should not put too much weight on the shape of the correlation ellipse for those two variables.</p>
<p>But it might be interesting to view the smoothed distribution of values of depreciation_per_month for each of the variants.</p>
<div class="cell" data-hash="visualisation_cache/html/unnamed-chunk-6_e68e4b6c3e26565d1065b3b1dcd6a5bd">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb7-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(ggridges)</span>
<span id="cb7-2"></span>
<span id="cb7-3">cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(</span>
<span id="cb7-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> depreciation_per_month, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> variant, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">fill =</span> variant, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">color =</span> variant)</span>
<span id="cb7-5">) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_density_ridges</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">alpha =</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">show.legend =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">FALSE</span>)</span></code></pre></div></div>
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://www.oldgang.net/notebooks/posts/car_prices/02.visualisation/visualisation_files/figure-html/unnamed-chunk-6-1.png" class="img-fluid figure-img" width="672"></p>
</figure>
</div>
</div>
</div>
<p>It is noticeable how much narrower the range of depreciation per month is for the cheapest model - the SE-L variant. This is seen even more clearly with a box and whisker plot.</p>
<div class="cell" data-hash="visualisation_cache/html/unnamed-chunk-7_c1110a15e915d0d056db9eaa487a8307">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb8-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(</span>
<span id="cb8-2">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> cars,</span>
<span id="cb8-3">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">mapping =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> depreciation_per_month, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> variant)</span>
<span id="cb8-4">) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_boxplot</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">notch =</span> T) </span></code></pre></div></div>
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://www.oldgang.net/notebooks/posts/car_prices/02.visualisation/visualisation_files/figure-html/unnamed-chunk-7-1.png" class="img-fluid figure-img" width="672"></p>
</figure>
</div>
</div>
</div>
<p>In this plot we have requested a <code>notch</code> on each plot. If the notches on two plots do not overlap then we can assume, with 95% confidence, that the medians are different. So between our variants the median depreciation_per_month is significantly different for all but the SE-L and SE-L Lux variants.</p>
<p>It doesn’t seem too surprising that there would be some vehicles with high levels of depreciation but the low levels are worth examining.</p>
<div class="cell" data-hash="visualisation_cache/html/unnamed-chunk-8_9f6a36dccab5cb8051205a610ea66442">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb9-1">cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> </span>
<span id="cb9-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">arrange</span>(depreciation_per_month) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb9-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(model, variant, miles, price, price_new,</span>
<span id="cb9-4">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm =</span> depreciation_per_month) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb9-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">head</span>(<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">5</span>)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code># A tibble: 5 × 6
  model       variant   miles price price_new   dpm
  &lt;fct&gt;       &lt;fct&gt;     &lt;dbl&gt; &lt;dbl&gt;     &lt;dbl&gt; &lt;dbl&gt;
1 Mazda CX-30 GT Sport     10 31805     30915   0  
2 Mazda CX-30 Sport Lux     5 26500     26995  55  
3 Mazda CX-30 GT Sport   2705 29994     30915  61.4
4 Mazda CX-30 Sport Lux    25 27500     29005 100. 
5 Mazda CX-30 SE-L Lux  17548 21995     26145 106. </code></pre>
</div>
</div>
<p>We can see that these are all low mileage vehicles that are priced close to (or above in one case) our estimate of their new price.</p>
<p>We can introduce the value of the <code>engine</code> variable into our boxplot to see whether that has an impact on monthly depreciation.</p>
<div class="cell" data-hash="visualisation_cache/html/unnamed-chunk-9_309eddcdedca54331e7dd38801fcb852">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb11-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(</span>
<span id="cb11-2">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> cars,</span>
<span id="cb11-3">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">mapping =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> depreciation_per_month, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> variant, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">color=</span>engine)</span>
<span id="cb11-4">) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_boxplot</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">show.legend =</span> T, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">notch =</span> T) </span></code></pre></div></div>
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://www.oldgang.net/notebooks/posts/car_prices/02.visualisation/visualisation_files/figure-html/unnamed-chunk-9-1.png" class="img-fluid figure-img" width="672"></p>
</figure>
</div>
</div>
</div>
<p>Now the boxplot for each variant has been replace by two boxplots, one for each of the two available engines. The cheapest variant is only available in the e-Skyactiv G engine and so only has the one plot.</p>
<p>For each variant it appears as though the choice of engine also has a significant impact on the median monthly depreciation of the vehicle.</p>
<p>Swapping the Y-axis around and this time diplaying <code>engine</code> in place of <code>variant</code> shows us that even within vehicles with the same engine there is some significant difference in monthly depreciation between the variants.</p>
<div class="cell" data-hash="visualisation_cache/html/unnamed-chunk-10_602b53fb10776dd7057ce3e1c20e99ae">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb12-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ggplot</span>(</span>
<span id="cb12-2">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">data =</span> cars,</span>
<span id="cb12-3">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">mapping =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">aes</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">x =</span> depreciation_per_month, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">y =</span> engine, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">color=</span>variant)</span>
<span id="cb12-4">) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">geom_boxplot</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">show.legend =</span> T, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">notch =</span> T) </span></code></pre></div></div>
<div class="cell-output-display">
<div>
<figure class="figure">
<p><img src="https://www.oldgang.net/notebooks/posts/car_prices/02.visualisation/visualisation_files/figure-html/unnamed-chunk-10-1.png" class="img-fluid figure-img" width="672"></p>
</figure>
</div>
</div>
</div>
<p>Another observation that becomes clear from the last two plots is that for the cheaper engine, the e-Skyactiv G, there is a slightly smaller monthly depreciation with the SE-L Lux variant when compared with the cheaper SE-L variant.</p>
<p>We can examine the median values of depreciation_per_month by variant in tabular form and this looks to agree nicely with our boxplot above:</p>
<div class="cell" data-hash="visualisation_cache/html/unnamed-chunk-11_94a774abe8d4164884a78cc65ad1933a">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb13-1">cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb13-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm=</span>depreciation_per_month, variant, engine, drive) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb13-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(variant) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb13-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">n=</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">n</span>(), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">median_dpm =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(dpm, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">na.rm =</span> T)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb13-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">arrange</span>(median_dpm) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb13-6">  knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">variant</th>
<th style="text-align: right;">n</th>
<th style="text-align: right;">median_dpm</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">SE-L</td>
<td style="text-align: right;">32</td>
<td style="text-align: right;">195</td>
</tr>
<tr class="even">
<td style="text-align: left;">SE-L Lux</td>
<td style="text-align: right;">75</td>
<td style="text-align: right;">196</td>
</tr>
<tr class="odd">
<td style="text-align: left;">Sport Lux</td>
<td style="text-align: right;">177</td>
<td style="text-align: right;">223</td>
</tr>
<tr class="even">
<td style="text-align: left;">GT Sport</td>
<td style="text-align: right;">99</td>
<td style="text-align: right;">255</td>
</tr>
<tr class="odd">
<td style="text-align: left;">GT Sport Tech</td>
<td style="text-align: right;">110</td>
<td style="text-align: right;">290</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>By engine across all variants and drives:</p>
<div class="cell" data-hash="visualisation_cache/html/unnamed-chunk-12_f6ca9b0e71f3fac30a0bcea1e6f9a681">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb14-1">cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb14-2">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">dpm=</span>depreciation_per_month, variant, engine, drive) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb14-3">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(engine) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb14-4">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">n=</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">n</span>(), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">median_dpm =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(dpm, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">na.rm =</span> T)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb14-5">  <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">arrange</span>(median_dpm) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb14-6">  knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">engine</th>
<th style="text-align: right;">n</th>
<th style="text-align: right;">median_dpm</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: right;">209</td>
<td style="text-align: right;">208</td>
</tr>
<tr class="even">
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: right;">284</td>
<td style="text-align: right;">244</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>So the effect of the more expensive engine looks to be to increase the monthly depreciation by about £35 across all variants and drives.</p>
<p>By drive across all variants and engines:</p>
<div class="cell" data-hash="visualisation_cache/html/unnamed-chunk-13_0e087be2e849b72f58d6cb6912b414b8">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb15" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb15-1">cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb15-2">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(depreciation_per_month, variant, engine, drive) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb15-3">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(drive) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb15-4">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">n=</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">n</span>(), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">median_dpm =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(depreciation_per_month, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">na.rm =</span> T)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb15-5">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">arrange</span>(median_dpm) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb15-6">    knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">drive</th>
<th style="text-align: right;">n</th>
<th style="text-align: right;">median_dpm</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">2WD</td>
<td style="text-align: right;">468</td>
<td style="text-align: right;">228</td>
</tr>
<tr class="even">
<td style="text-align: left;">AWD</td>
<td style="text-align: right;">25</td>
<td style="text-align: right;">305</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>The effect all-wheel-drive increases the monthly depreciation by about £75 across all variants and engines. Or by all combinations of variant, engine and drive.</p>
<div class="cell" data-hash="visualisation_cache/html/unnamed-chunk-14_9585ea53cb0af49c1cf06f210932b893">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb16" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb16-1">cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb16-2">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(depreciation_per_month, variant, engine, drive) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb16-3">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">group_by</span>(variant, engine, drive) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb16-4">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">summarise</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">n=</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">n</span>(), <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">median_dpm =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">median</span>(depreciation_per_month, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">na.rm =</span> T)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb16-5">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">arrange</span>(median_dpm) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb16-6">    knitr<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">::</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">kable</span>(<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">digits=</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>)</span></code></pre></div></div>
<div class="cell-output-display">
<table class="caption-top table table-sm table-striped small">
<thead>
<tr class="header">
<th style="text-align: left;">variant</th>
<th style="text-align: left;">engine</th>
<th style="text-align: left;">drive</th>
<th style="text-align: right;">n</th>
<th style="text-align: right;">median_dpm</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td style="text-align: left;">SE-L Lux</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: left;">2WD</td>
<td style="text-align: right;">48</td>
<td style="text-align: right;">186</td>
</tr>
<tr class="even">
<td style="text-align: left;">SE-L</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: left;">2WD</td>
<td style="text-align: right;">32</td>
<td style="text-align: right;">195</td>
</tr>
<tr class="odd">
<td style="text-align: left;">SE-L Lux</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: left;">2WD</td>
<td style="text-align: right;">27</td>
<td style="text-align: right;">218</td>
</tr>
<tr class="even">
<td style="text-align: left;">Sport Lux</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: left;">2WD</td>
<td style="text-align: right;">88</td>
<td style="text-align: right;">223</td>
</tr>
<tr class="odd">
<td style="text-align: left;">GT Sport</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: left;">2WD</td>
<td style="text-align: right;">27</td>
<td style="text-align: right;">233</td>
</tr>
<tr class="even">
<td style="text-align: left;">Sport Lux</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: left;">2WD</td>
<td style="text-align: right;">89</td>
<td style="text-align: right;">241</td>
</tr>
<tr class="odd">
<td style="text-align: left;">GT Sport Tech</td>
<td style="text-align: left;">e-Skyactiv G</td>
<td style="text-align: left;">2WD</td>
<td style="text-align: right;">14</td>
<td style="text-align: right;">252</td>
</tr>
<tr class="even">
<td style="text-align: left;">GT Sport</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: left;">2WD</td>
<td style="text-align: right;">60</td>
<td style="text-align: right;">253</td>
</tr>
<tr class="odd">
<td style="text-align: left;">GT Sport Tech</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: left;">2WD</td>
<td style="text-align: right;">83</td>
<td style="text-align: right;">285</td>
</tr>
<tr class="even">
<td style="text-align: left;">GT Sport</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: left;">AWD</td>
<td style="text-align: right;">12</td>
<td style="text-align: right;">304</td>
</tr>
<tr class="odd">
<td style="text-align: left;">GT Sport Tech</td>
<td style="text-align: left;">e-Skyactiv X</td>
<td style="text-align: left;">AWD</td>
<td style="text-align: right;">13</td>
<td style="text-align: right;">306</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>It soon becomes clear that it is difficult to settle on a single method of determining which variables are most explanatory in understanding monthly depreciation. And also, exactly what the numerical effect of the choice of a particular variant, engine or drive might be on monthly depreciation. We have conveniently ignored the effect of the age of the vehicle or the number of miles it has been driven and we know that these are likely to have a big effect.</p>
<p>In the next notebook we will look to model the effect of all of these variables on monthly depreciation.</p>
<p>Next: <a href="../../../../notebooks/posts/car_prices/03.modelling/modelling.html">Mazda CX-30 Price Data - Modelling</a></p>



 ]]></description>
  <category>R</category>
  <category>Car Price</category>
  <category>Mazda CX-30</category>
  <guid>https://www.oldgang.net/notebooks/posts/car_prices/02.visualisation/visualisation.html</guid>
  <pubDate>Tue, 04 Apr 2023 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Mazda CX-30 Price Data - Preparation</title>
  <dc:creator>John Bates</dc:creator>
  <link>https://www.oldgang.net/notebooks/posts/car_prices/01.preparation/preparation.html</link>
  <description><![CDATA[ 




<p>The aim of this notebook is to prepare an R dataframe for analysis. We start with some data that has been collected about car prices for a number of variants of the Mazda CX-30. The car prices are in £ Sterling and have been obtained from a number of sources.</p>
<p>The processing in this notebook will result in the creation of a serialisation of a cleaned dataframe to disk in R’s native RDS format.</p>
<p>We use the term dataframe but will actually be using a Tidyverse <a href="https://tibble.tidyverse.org"><code>tibble</code></a> which can be thought of as an enhanced dataframe. The tibble package, and several others that we will be using, are made available by referencing the <code>tidyverse</code> package.</p>
<div class="callout callout-style-default callout-note callout-titled">
<div class="callout-header d-flex align-content-center">
<div class="callout-icon-container">
<i class="callout-icon"></i>
</div>
<div class="callout-title-container flex-fill">
Note
</div>
</div>
<div class="callout-body-container callout-body">
<p>You can install the tidyverse package by running the one-off command:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb1-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">install.packages</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"tidyverse"</span>)</span></code></pre></div></div>
</div>
</div>
<div class="cell" data-hash="preparation_cache/html/unnamed-chunk-1_39dded8ade370216893a4d936db09715">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb2-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">library</span>(tidyverse)</span></code></pre></div></div>
</div>
<p>Our data is already in a CSV file on disk that we can read into a dataframe and then we can convert the dataframe into a tibble.</p>
<div class="cell" data-hash="preparation_cache/html/unnamed-chunk-2_4dc0054518688f1050f12f653946c637">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb3-1">cars <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">read_csv</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"mazda.csv"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as_tibble</span>()</span></code></pre></div></div>
</div>
<p>The pipe-forward operator, which is similar (but not identical) to the one found in the <a href="https://dl.acm.org/doi/pdf/10.1145/3386325">F# language and even earlier dialects of ML</a>, takes the result of the command to its left and passes it as the first argument of the function on its right. So the above code fragment is functionally the same as this:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb4-1">cars <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as_tibble</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">read_csv</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"mazda.csv"</span>))</span></code></pre></div></div>
<p>But using the pipe-forward operator, especially when chained in runs of more than one, makes the code easier to read.</p>
<div class="cell" data-hash="preparation_cache/html/unnamed-chunk-3_83df23807f507d019bf683230ef4ab87">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb5-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str</span>(cars)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>tibble [816 × 7] (S3: tbl_df/tbl/data.frame)
 $ rowno      : num [1:816] 1 2 3 4 5 6 7 8 9 10 ...
 $ id         : num [1:816] 2.02e+14 2.02e+14 2.02e+14 2.02e+14 2.02e+14 ...
 $ title      : chr [1:816] "Mazda Cx-30" "Mazda CX-30" "Mazda Cx-30" "Mazda Cx-30" ...
 $ subtitle   : chr [1:816] "2.0 Skyactiv-X MHEV GT Sport Tech 5dr" "2.0 e-Skyactiv G MHEV SE-L 5dr" "SE-L LUX MHEV 2.0 5dr" "2.0 e-Skyactiv X MHEV GT Sport Tech 5dr Hatchback" ...
 $ price      : num [1:816] 24990 18785 21995 29994 34745 ...
 $ spec       : chr [1:816] "2021 (71 reg) SUV 6,542 miles 2.0L 186PS Manual Petrol Full service history" "2021 SUV 14,814 miles 2.0L 122PS Manual Petrol" "2020 (20 reg) SUV 17,548 miles 2.0L 122PS Manual Petrol" "2023 (23 reg) SUV 225 miles 2.0L 186PS Manual Petrol" ...
 $ advert_date: POSIXct[1:816], format: "2023-04-03 16:26:50" "2023-04-03 16:26:50" ...</code></pre>
</div>
</div>
<p>Running <code>str</code> on the tibble shows that we have 816 rows on 7 columns. Two rows are badly named: <code>title</code> should be named <code>model</code> and <code>subtitle</code> would be better named <code>variant_detail</code> because it contains a collection of information that we can examine to determine more about the particular variant of the model that each row describes. We can rename the rows by using the <code>rename</code> function from the <code>dplyr</code> package (which is itself part of the umbrella <code>tidyverse</code> package)</p>
<div class="cell" data-hash="preparation_cache/html/unnamed-chunk-4_e25a20ecab2a0d8dfa1bc9cbde1126f5">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb7-1">cars <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">rename</span>(</span>
<span id="cb7-2">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">model =</span> title,</span>
<span id="cb7-3">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">variant_detail =</span> subtitle</span>
<span id="cb7-4">)</span></code></pre></div></div>
</div>
<p>Examining the contents of the tibble we can see that there are some rows for models other than the CX-30.</p>
<div class="cell" data-hash="preparation_cache/html/unnamed-chunk-5_34985a378899758a58c4da01fb705a8e">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb8-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">table</span>(cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>model)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>
       Hyundai Tucson           Mazda Cx-30           Mazda CX-30 
                    6                   314                   489 
Mazda CX-30 HATCHBACK            Mazda CX-5            Mazda CX30 
                    3                     2                     2 </code></pre>
</div>
</div>
<p>Most are variations on the CX-30 model but the Hyundai Tucson and the Mazda CX-5 rows will need to be removed. We can do this with the <code>filter</code> function of the <code>dplyr</code> package. We also don’t need the <code>rowno</code>, <code>id</code> or <code>advert_date</code> columns, so we remove them using the <code>select</code> function of the ‘dplyr’ package:</p>
<div class="cell" data-hash="preparation_cache/html/unnamed-chunk-6_7f6f09bb99fa25aa3d933db3664718f9">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb10-1">cars <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb10-2">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(id, rowno, advert_date)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb10-3">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(</span>
<span id="cb10-4">        model <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Hyundai Tucson"</span>,</span>
<span id="cb10-5">        model <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Mazda CX-5"</span></span>
<span id="cb10-6">    )</span>
<span id="cb10-7"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">head</span>(cars)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code># A tibble: 6 × 4
  model       variant_detail                                       price spec   
  &lt;chr&gt;       &lt;chr&gt;                                                &lt;dbl&gt; &lt;chr&gt;  
1 Mazda Cx-30 2.0 Skyactiv-X MHEV GT Sport Tech 5dr                24990 2021 (…
2 Mazda CX-30 2.0 e-Skyactiv G MHEV SE-L 5dr                       18785 2021 S…
3 Mazda Cx-30 SE-L LUX MHEV 2.0 5dr                                21995 2020 (…
4 Mazda Cx-30 2.0 e-Skyactiv X MHEV GT Sport Tech 5dr Hatchback    29994 2023 (…
5 Mazda CX-30 2.0 186ps 2WD GT Sport Tech Auto / Stone Leather 5dr 34745 SUV 2.…
6 Mazda CX-30 2.0 e-SKYACTIV G MHEV SE-L Lux Euro 6 (s/s) 5dr      25335 SUV 2.…</code></pre>
</div>
</div>
<p>It is easy to see from the remaining 4 columns most of the useful information about the variant of the car lies within the <code>variant_detail</code> and the <code>spec</code> columns:</p>
<div class="cell" data-hash="preparation_cache/html/unnamed-chunk-7_e7a74002834a721ab982494ae9a51440">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb12-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">head</span>(cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>variant_detail)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>[1] "2.0 Skyactiv-X MHEV GT Sport Tech 5dr"               
[2] "2.0 e-Skyactiv G MHEV SE-L 5dr"                      
[3] "SE-L LUX MHEV 2.0 5dr"                               
[4] "2.0 e-Skyactiv X MHEV GT Sport Tech 5dr Hatchback"   
[5] "2.0 186ps 2WD GT Sport Tech Auto / Stone Leather 5dr"
[6] "2.0 e-SKYACTIV G MHEV SE-L Lux Euro 6 (s/s) 5dr"     </code></pre>
</div>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb14-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">head</span>(cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>spec)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>[1] "2021 (71 reg) SUV 6,542 miles 2.0L 186PS Manual Petrol Full service history"         
[2] "2021 SUV 14,814 miles 2.0L 122PS Manual Petrol"                                      
[3] "2020 (20 reg) SUV 17,548 miles 2.0L 122PS Manual Petrol"                             
[4] "2023 (23 reg) SUV 225 miles 2.0L 186PS Manual Petrol"                                
[5] "SUV 2.0L 186PS Manual Petrol First year road tax included Full manufacturer warranty"
[6] "SUV 2.0L 122PS Manual Petrol First year road tax included Full manufacturer warranty"</code></pre>
</div>
</div>
<p>The task here is to identify the useful information that could be extracted from these two columns and then write functions to extract that information into new columns in the tibble. We show how this is done using the <code>mutate</code> function of the <code>dplyr</code> package which allows us to change the value of existing columns or to create new columns. Where the calculation of value for a column is anything other than trivial the work has been handed off to a function. You can see the definition of those functions by clicking the “show the code” link below.</p>
<div class="cell" data-hash="preparation_cache/html/unnamed-chunk-8_44fe7e99261faa8f33c68a7e437ac8fa">
<details class="code-fold">
<summary>Show the code</summary>
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb16" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb16-1">bhp_from_spec <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(spec){</span>
<span id="cb16-2">    bhp <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_extract</span>(spec, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"([:digit:]{3})(PS|BHP)"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">group =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)</span>
<span id="cb16-3">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">return</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as.numeric</span>(bhp))</span>
<span id="cb16-4">}</span>
<span id="cb16-5">miles_from_spec <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(spec){</span>
<span id="cb16-6">    miles <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_extract</span>(spec, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"([0-9,]+) miles"</span>, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">group =</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>)</span>
<span id="cb16-7">    miles <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_replace</span>(miles, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">","</span>, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">""</span>)</span>
<span id="cb16-8">    miles <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">if_else</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">is.na</span>(miles), <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>, <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as.numeric</span>(miles))</span>
<span id="cb16-9">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">return</span>(miles)</span>
<span id="cb16-10">}</span>
<span id="cb16-11">new_used_from_spec_and_age <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(spec, age){</span>
<span id="cb16-12">    miles <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">miles_from_spec</span>(spec)</span>
<span id="cb16-13">    warranty <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_detect</span>(</span>
<span id="cb16-14">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_to_lower</span>(spec),</span>
<span id="cb16-15">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"full *manufacturer *warranty"</span></span>
<span id="cb16-16">    )</span>
<span id="cb16-17">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">return</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">if_else</span>(</span>
<span id="cb16-18">        miles <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&amp;</span> (warranty <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">TRUE</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|</span> age <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>),</span>
<span id="cb16-19">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"New"</span>,</span>
<span id="cb16-20">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Used"</span></span>
<span id="cb16-21">    ))</span>
<span id="cb16-22">}</span>
<span id="cb16-23">reg_from_spec <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(spec){</span>
<span id="cb16-24">    matches <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_match</span>(spec, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"(?&lt;year&gt;[0-9]{4}) </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\\</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">((?&lt;reg&gt;[0-9]{2}) reg</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\\</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">)"</span>)</span>
<span id="cb16-25">    reg <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> matches[, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"reg"</span>]</span>
<span id="cb16-26">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">return</span>(reg)</span>
<span id="cb16-27">}</span>
<span id="cb16-28">year_from_spec <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(spec){</span>
<span id="cb16-29">    matches1 <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_match</span>(spec, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"(?&lt;year&gt;[0-9]{4}) </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\\</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">((?&lt;reg&gt;[0-9]{2}) reg</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\\</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">)"</span>)</span>
<span id="cb16-30">    year1 <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> matches1[, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"year"</span>]</span>
<span id="cb16-31">    matches2 <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_match</span>(spec, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"(?&lt;year&gt;20[12][0-9])"</span>)</span>
<span id="cb16-32">    year2 <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> matches2[, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"year"</span>]</span>
<span id="cb16-33">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">return</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">if_else</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">is.na</span>(year1), year2, year1))</span>
<span id="cb16-34">}</span>
<span id="cb16-35">age_in_months <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(reg){</span>
<span id="cb16-36">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#table_offset_in_months &lt;- interval(ymd("20230301"), today()) / dmonths() # nolint</span></span>
<span id="cb16-37">    table_offset_in_months <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span></span>
<span id="cb16-38">    months <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> table_offset_in_months <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb16-39">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">case_when</span>(</span>
<span id="cb16-40">        reg <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">23</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0</span>,</span>
<span id="cb16-41">        reg <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">72</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.5</span>,</span>
<span id="cb16-42">        reg <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">22</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.0</span>,</span>
<span id="cb16-43">        reg <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">71</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.5</span>,</span>
<span id="cb16-44">        reg <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">21</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2.0</span>,</span>
<span id="cb16-45">        reg <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">70</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2.5</span>,</span>
<span id="cb16-46">        reg <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">20</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.0</span>,</span>
<span id="cb16-47">        reg <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">69</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.5</span>,</span>
<span id="cb16-48">        reg <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">19</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">4.0</span>,</span>
<span id="cb16-49">        reg <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">68</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">4.5</span>,</span>
<span id="cb16-50">        reg <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">18</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">5.0</span>,</span>
<span id="cb16-51">        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.default =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">NA</span></span>
<span id="cb16-52">        )</span>
<span id="cb16-53">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">return</span>(months)</span>
<span id="cb16-54">}</span>
<span id="cb16-55">age_in_months_from_year <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(spec){</span>
<span id="cb16-56">    matches <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_match</span>(spec, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"(?&lt;year&gt;20[12][0-9])"</span>)</span>
<span id="cb16-57">    year <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> matches[, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"year"</span>]</span>
<span id="cb16-58">    <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#table_offset_in_months &lt;- interval(ymd("20230301"), today()) / dmonths() # nolint</span></span>
<span id="cb16-59">    table_offset_in_months <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span></span>
<span id="cb16-60">    months <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> table_offset_in_months <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span></span>
<span id="cb16-61">        <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">12</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">*</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">case_when</span>(</span>
<span id="cb16-62">        year <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2023</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">0.0</span>,</span>
<span id="cb16-63">        year <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2022</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">1.0</span>,</span>
<span id="cb16-64">        year <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2021</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">2.0</span>,</span>
<span id="cb16-65">        year <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2020</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">3.0</span>,</span>
<span id="cb16-66">        year <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2019</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">4.0</span>,</span>
<span id="cb16-67">        year <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2018</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="fl" style="color: #AD0000;
background-color: null;
font-style: inherit;">5.0</span>,</span>
<span id="cb16-68">        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.default =</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">NA</span></span>
<span id="cb16-69">        )</span>
<span id="cb16-70">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">return</span>(months)</span>
<span id="cb16-71"></span>
<span id="cb16-72">}</span>
<span id="cb16-73">variant_from_detail <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(variant_detail){</span>
<span id="cb16-74">    detail <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_to_lower</span>(variant_detail)</span>
<span id="cb16-75">    test <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> \(pat) <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_detect</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fixed</span>(detail), pat)</span>
<span id="cb16-76">    variant <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">case_when</span>(</span>
<span id="cb16-77">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">test</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"se-l lux"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SE-L Lux"</span>,</span>
<span id="cb16-78">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">test</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"se-l"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"SE-L"</span>,</span>
<span id="cb16-79">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">test</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sport lux"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Sport Lux"</span>,</span>
<span id="cb16-80">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">test</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"gt sport tech"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"GT Sport Tech"</span>,</span>
<span id="cb16-81">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">test</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"gt sport"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"GT Sport"</span>,</span>
<span id="cb16-82">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">test</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"anniversary edition"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"100th Anniversary Edition"</span>,</span>
<span id="cb16-83">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">test</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"spt lux"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Sport Lux"</span>,</span>
<span id="cb16-84">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">test</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sport nav"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Sport Nav"</span>,</span>
<span id="cb16-85">        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.default =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_glue</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"XXXX: {variant_detail}"</span>)</span>
<span id="cb16-86">    )</span>
<span id="cb16-87">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">return</span>(variant)</span>
<span id="cb16-88">}</span>
<span id="cb16-89">drive_from_detail <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(variant_detail){</span>
<span id="cb16-90">    detail <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_to_lower</span>(variant_detail)</span>
<span id="cb16-91">    test <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> \(pat) <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_detect</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fixed</span>(detail), pat)</span>
<span id="cb16-92">    drive <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">case_when</span>(</span>
<span id="cb16-93">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">test</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"awd"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"AWD"</span>,</span>
<span id="cb16-94">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">test</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"4wd"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"AWD"</span>,</span>
<span id="cb16-95">        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.default =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"2WD"</span></span>
<span id="cb16-96">    )</span>
<span id="cb16-97">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">return</span>(drive)</span>
<span id="cb16-98">}</span>
<span id="cb16-99">engine_from_detail_and_bhp <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(variant_detail, bhp) {</span>
<span id="cb16-100">    detail <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_to_lower</span>(variant_detail)</span>
<span id="cb16-101">    test <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> \(pat) <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_detect</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fixed</span>(detail), pat)</span>
<span id="cb16-102">    variant1 <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">case_when</span>(</span>
<span id="cb16-103">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">test</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"skyactiv x"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"e-Skyactiv X"</span>,</span>
<span id="cb16-104">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">test</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"skyactiv-x"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"e-Skyactiv X"</span>,</span>
<span id="cb16-105">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">test</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"skyactiv g"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"e-Skyactiv G"</span>,</span>
<span id="cb16-106">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">test</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"skyactiv-g"</span>) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"e-Skyactiv G"</span>,</span>
<span id="cb16-107">    )</span>
<span id="cb16-108">    variant2 <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">if_else</span>(</span>
<span id="cb16-109">        bhp <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"High"</span>,</span>
<span id="cb16-110">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"e-Skyactiv X"</span>,</span>
<span id="cb16-111">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"e-Skyactiv G"</span></span>
<span id="cb16-112">    )</span>
<span id="cb16-113">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">return</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">if_else</span>(</span>
<span id="cb16-114">        <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">is.na</span>(variant1),</span>
<span id="cb16-115">        variant1,</span>
<span id="cb16-116">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">if_else</span>(</span>
<span id="cb16-117">            <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">is.na</span>(variant2),</span>
<span id="cb16-118">            variant2,</span>
<span id="cb16-119">            <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_glue</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"XXXX: {variant_detail}"</span>)</span>
<span id="cb16-120">        )</span>
<span id="cb16-121">    ))</span>
<span id="cb16-122">}</span>
<span id="cb16-123">price_new_from_variant_engine_and_drive <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">function</span>(variant, engine, drive) { <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># nolint</span></span>
<span id="cb16-124">    key <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">paste</span>(variant, drive, engine, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">sep =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"/"</span>)</span>
<span id="cb16-125">    key <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_to_lower</span>(key)</span>
<span id="cb16-126">    price_new <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">case_when</span>(</span>
<span id="cb16-127">        key <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"se-l lux/2wd/e-skyactiv g"</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"26145"</span>,</span>
<span id="cb16-128">        key <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"se-l lux/2wd/e-skyactiv x"</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"28005"</span>,</span>
<span id="cb16-129">        key <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"se-l/2wd/e-skyactiv g"</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"24645"</span>,</span>
<span id="cb16-130">        key <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sport lux/2wd/e-skyactiv g"</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"26995"</span>,</span>
<span id="cb16-131">        key <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"sport lux/2wd/e-skyactiv x"</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"29005"</span>,</span>
<span id="cb16-132">        key <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"gt sport edition/2wd/e-skyactiv g"</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"28855"</span>,</span>
<span id="cb16-133">        key <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"gt sport edition/2wd/e-skyactiv x"</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"31115"</span>,</span>
<span id="cb16-134">        key <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"gt sport edition/awd/e-skyactiv x"</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"33355"</span>,</span>
<span id="cb16-135">        key <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"gt sport/2wd/e-skyactiv g"</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"28905"</span>,</span>
<span id="cb16-136">        key <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"gt sport/2wd/e-skyactiv x"</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"30915"</span>,</span>
<span id="cb16-137">        key <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"gt sport/awd/e-skyactiv x"</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"33655"</span>,</span>
<span id="cb16-138">        key <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"gt sport tech edition/2wd/e-skyactiv g"</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"29755"</span>,</span>
<span id="cb16-139">        key <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"gt sport tech edition/2wd/e-skyactiv x"</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"32015"</span>,</span>
<span id="cb16-140">        key <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"gt sport tech edition/awd/e-skyactiv x"</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"34255"</span>,</span>
<span id="cb16-141">        key <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"gt sport tech/2wd/e-skyactiv g"</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"29805"</span>,</span>
<span id="cb16-142">        key <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"gt sport tech/2wd/e-skyactiv x"</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"31815"</span>,</span>
<span id="cb16-143">        key <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">==</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"gt sport tech/awd/e-skyactiv x"</span> <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">~</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"34555"</span>,</span>
<span id="cb16-144">        <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.default =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_glue</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"XXXX: {variant} {engine} {drive}"</span>)</span>
<span id="cb16-145">    )</span>
<span id="cb16-146">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">return</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as.numeric</span>(price_new))</span>
<span id="cb16-147">}</span></code></pre></div></div>
</details>
</div>
<p>The main body of the code uses those functions to determine the value of a number of new columns.</p>
<div class="cell" data-hash="preparation_cache/html/unnamed-chunk-9_9a0f0fe7a6011cefce476bfdab736bfe">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb17" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb17-1">cars <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb17-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">mutate</span>(</span>
<span id="cb17-3">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">model =</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Mazda CX-30"</span>,</span>
<span id="cb17-4">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">variant =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">variant_from_detail</span>(variant_detail),</span>
<span id="cb17-5">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">drive =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">drive_from_detail</span>(variant_detail),</span>
<span id="cb17-6">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">fuel =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">if_else</span>(</span>
<span id="cb17-7">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_detect</span>(spec, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Petrol"</span>),</span>
<span id="cb17-8">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Petrol"</span>,</span>
<span id="cb17-9">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Diesel"</span>,</span>
<span id="cb17-10">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Unknown"</span></span>
<span id="cb17-11">    ),</span>
<span id="cb17-12">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">price =</span> price,</span>
<span id="cb17-13">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">transmission =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">if_else</span>(</span>
<span id="cb17-14">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str_detect</span>(spec, <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Manual"</span>),</span>
<span id="cb17-15">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Manual"</span>,</span>
<span id="cb17-16">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Automatic"</span>,</span>
<span id="cb17-17">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Unknown"</span></span>
<span id="cb17-18">    ),</span>
<span id="cb17-19">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">bhp =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">if_else</span>(</span>
<span id="cb17-20">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">bhp_from_spec</span>(spec) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">175</span>,</span>
<span id="cb17-21">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"High"</span>,</span>
<span id="cb17-22">        <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Low"</span></span>
<span id="cb17-23">    ),</span>
<span id="cb17-24">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">engine =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">engine_from_detail_and_bhp</span>(variant_detail, bhp),</span>
<span id="cb17-25">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">price_new =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">price_new_from_variant_engine_and_drive</span>(variant, engine, drive), <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># nolint: line_length_linter.</span></span>
<span id="cb17-26">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">miles =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">miles_from_spec</span>(spec),</span>
<span id="cb17-27">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">reg =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">reg_from_spec</span>(spec),</span>
<span id="cb17-28">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">year =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">year_from_spec</span>(spec),</span>
<span id="cb17-29">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">age_in_months =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">if_else</span>(</span>
<span id="cb17-30">        <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">is.na</span>(reg),</span>
<span id="cb17-31">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">age_in_months</span>(reg),</span>
<span id="cb17-32">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">age_in_months_from_year</span>(spec)</span>
<span id="cb17-33">    ),</span>
<span id="cb17-34">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">mid_age_in_months =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">if_else</span>(</span>
<span id="cb17-35">        <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">is.na</span>(reg),</span>
<span id="cb17-36">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">age_in_months</span>(reg)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>,</span>
<span id="cb17-37">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">age_in_months_from_year</span>(spec)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span></span>
<span id="cb17-38">    ),</span>
<span id="cb17-39">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">new_used =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">new_used_from_spec_and_age</span>(spec, age_in_months),</span>
<span id="cb17-40">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">spec =</span> spec,</span>
<span id="cb17-41">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">depreciation =</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">if_else</span>(price_new <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> price, price_new <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> price, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>),</span>
<span id="cb17-42">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">depreciation_per_month =</span> depreciation <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> mid_age_in_months,</span>
<span id="cb17-43">    <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">miles_per_month =</span> miles <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> mid_age_in_months</span>
<span id="cb17-44">)</span></code></pre></div></div>
</div>
<p>Quite a lot is going on here. In particular,</p>
<ol type="1">
<li>All of the assignments and operations are on vectors of data.</li>
<li>New or mutated columns are able to be defined in terms of previously named columns.</li>
</ol>
<p>R is an array processing language which means that it has operations that are capable of working on a vector of values, so there are no manually written loops in the code above and even the if_else tests apply to a vector of values.</p>
<p>In the case where we appear to be assigning a scalar value (“Mazda CX-30”) to the column <code>model</code> R will arrange that the scalar value is recycled as many times as required to fill the entire vector value of the column.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb18" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb18-1">model <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Mazda CX-30"</span>,</span></code></pre></div></div>
<p>In the case where we are comparing the value of a column with a constant scalar value:</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb19" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb19-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">bhp_from_spec</span>(spec) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">175</span>,</span></code></pre></div></div>
<p>R will recycle the constant (175) to be a vector of the same length as the vector returned by the call to <code>bhp_from_spec(spec)</code> allowing the comparison to be made between two vectors of equal length and resulting in a vector of TRUE or FALSE values.</p>
<p>We calculated <code>depreciation_per_month</code> and <code>miles_per_month</code> from <code>mid_age_in_months</code> which was in turn calculated from <code>reg</code> which was determined from <code>spec</code>.</p>
<p>We now have a tibble with many more columns:</p>
<div class="cell" data-hash="preparation_cache/html/unnamed-chunk-10_f39fac03385046d4f5413d4746ae2a07">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb20" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb20-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">str</span>(cars)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>tibble [808 × 20] (S3: tbl_df/tbl/data.frame)
 $ model                 : chr [1:808] "Mazda CX-30" "Mazda CX-30" "Mazda CX-30" "Mazda CX-30" ...
 $ variant_detail        : chr [1:808] "2.0 Skyactiv-X MHEV GT Sport Tech 5dr" "2.0 e-Skyactiv G MHEV SE-L 5dr" "SE-L LUX MHEV 2.0 5dr" "2.0 e-Skyactiv X MHEV GT Sport Tech 5dr Hatchback" ...
 $ price                 : num [1:808] 24990 18785 21995 29994 34745 ...
 $ spec                  : chr [1:808] "2021 (71 reg) SUV 6,542 miles 2.0L 186PS Manual Petrol Full service history" "2021 SUV 14,814 miles 2.0L 122PS Manual Petrol" "2020 (20 reg) SUV 17,548 miles 2.0L 122PS Manual Petrol" "2023 (23 reg) SUV 225 miles 2.0L 186PS Manual Petrol" ...
 $ variant               : 'glue' chr [1:808] "GT Sport Tech" "SE-L" "SE-L Lux" "GT Sport Tech" ...
 $ drive                 : chr [1:808] "2WD" "2WD" "2WD" "2WD" ...
 $ fuel                  : chr [1:808] "Petrol" "Petrol" "Petrol" "Petrol" ...
 $ transmission          : chr [1:808] "Manual" "Manual" "Manual" "Manual" ...
 $ bhp                   : chr [1:808] "High" "Low" "Low" "High" ...
 $ engine                : 'glue' chr [1:808] "e-Skyactiv X" "e-Skyactiv G" "e-Skyactiv G" "e-Skyactiv X" ...
 $ price_new             : num [1:808] 31815 24645 26145 31815 31815 ...
 $ miles                 : num [1:808] 6542 14814 17548 225 0 ...
 $ reg                   : chr [1:808] "71" NA "20" "23" ...
 $ year                  : chr [1:808] "2021" "2021" "2020" "2023" ...
 $ age_in_months         : num [1:808] 18 24 36 0 NA NA NA 36 NA NA ...
 $ mid_age_in_months     : num [1:808] 21 30 39 3 NA NA NA 39 NA NA ...
 $ new_used              : chr [1:808] "Used" "Used" "Used" "Used" ...
 $ depreciation          : num [1:808] 6825 5860 4150 1821 0 ...
 $ depreciation_per_month: num [1:808] 325 195 106 607 NA ...
 $ miles_per_month       : num [1:808] 312 494 450 75 NA ...</code></pre>
</div>
</div>
<p>The columns <code>variant_detail</code> and <code>spec</code> are now redundant and we will drop them from the tibble later. But the determination of new column values has thrown up a few records for which we don’t have enough information and we will delete those rows.</p>
<div class="cell" data-hash="preparation_cache/html/unnamed-chunk-11_1658782bae3166e3c6901a99d9321475">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb22" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb22-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">table</span>(cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>variant)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>
100th Anniversary Edition                  GT Sport             GT Sport Tech 
                        4                       187                       200 
                     SE-L                  SE-L Lux                 Sport Lux 
                       62                       113                       241 
                Sport Nav 
                        1 </code></pre>
</div>
</div>
<p>The Mazda site defines only the models “SE-L”, “SE-L Lux”, “Sport Lux”, “GT Sport”, “GT Sport Tech”. We also have rows for “100th Anniversary Edition” and “Sport Nav” - There are a very small number of these and they are either bad data, old data or of no interest to us and so we will remove them.</p>
<div class="cell" data-hash="preparation_cache/html/unnamed-chunk-12_da5f17b2e08ab3327c387847a0dcdf25">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb24" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb24-1">(cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">is.na</span>(price_new)) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">count</span>())[[<span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>]]</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>[1] 29</code></pre>
</div>
</div>
<p>We have written a function to determine the new price of each of the vehicles. The new price can be found from the Mazda site using a combination of variant, engine size and drive (2WD or AWD). We want to be able to use the new price of a given vehicle to help us estimate how much the vehicle has depreciated over time.</p>
<p>The above query shows us that for a small number of rows we were unable to find a price for the given combination of these column values (For example, some of the lower priced variants are not available with a large engine size or four wheel drive). Where such a combination is found our new price lookup function returns NA - we will remove those rows from the data too:</p>
<div class="cell" data-hash="preparation_cache/html/unnamed-chunk-13_ca9d3cc423ed7a5dcf5a2102a09a8d0d">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb26" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb26-1">cars <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb26-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">filter</span>(</span>
<span id="cb26-3">    variant <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"100th Anniversary Edition"</span>,</span>
<span id="cb26-4">    variant <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Sport Nav"</span>,</span>
<span id="cb26-5">    <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">is.na</span>(price_new)</span>
<span id="cb26-6">)</span></code></pre></div></div>
</div>
<p>Next we create factors for those columns that are to be treated as such:</p>
<div class="cell" data-hash="preparation_cache/html/unnamed-chunk-14_4968c5778caa607cdbadb8720114bedb">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb27" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb27-1">cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>model <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as_factor</span>(cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>model)</span>
<span id="cb27-2">cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>variant <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span></span>
<span id="cb27-3">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as_factor</span>(cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>variant) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb27-4">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fct_reorder</span>(cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>price_new)</span>
<span id="cb27-5">cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>drive <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as_factor</span>(cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>drive)</span>
<span id="cb27-6">cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>engine <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span></span>
<span id="cb27-7">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as_factor</span>(cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>engine) <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb27-8">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">fct_reorder</span>(cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>price_new)</span>
<span id="cb27-9">cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>new_used <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as_factor</span>(cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>new_used)</span>
<span id="cb27-10">cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>reg <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as_factor</span>(cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>reg)</span>
<span id="cb27-11">cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>fuel <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as_factor</span>(cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>fuel)</span>
<span id="cb27-12">cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>transmission <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as_factor</span>(cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>transmission)</span>
<span id="cb27-13">cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>bhp <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">as_factor</span>(cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>bhp)</span></code></pre></div></div>
</div>
<p>The <code>as_factor</code> function is part of the tidyverse <code>forcats</code> package which makes it easier to work with factors than using the built-in R factor support. The <code>fct_reorder</code> function has allowed us to order the variant factor so that it is arranged in order of increasing (median) new price - sorted from cheapest variant to most expensive. We do the same kind of ordering for the engine - the “e-Skyactiv G” engine is cheaper than the “e-Skyactiv X” engine.</p>
<p>So now:</p>
<div class="cell" data-hash="preparation_cache/html/unnamed-chunk-15_f995c494ad8943e5e09b6c8ad9440c13">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb28" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb28-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">table</span>(cars<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span>variant)</span></code></pre></div></div>
<div class="cell-output cell-output-stdout">
<pre><code>
         SE-L      SE-L Lux     Sport Lux      GT Sport GT Sport Tech 
           42           113           237           187           200 </code></pre>
</div>
</div>
<p>This improves the appearance of charts and tables that involve the vehicle variant by displaying them in increasing order of cost.</p>
<p>Finally we select the final set of columns that we want to see in our tibble and we save the tibble to a disk file for use in later analyses.</p>
<div class="cell" data-hash="preparation_cache/html/unnamed-chunk-16_bb972cba5b15469b3b3a8069b02b6ec8">
<div class="code-copy-outer-scaffold"><div class="sourceCode cell-code" id="cb30" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb30-1">cars <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> cars <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">|&gt;</span></span>
<span id="cb30-2"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">select</span>(<span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">c</span>(</span>
<span id="cb30-3">    model, variant, drive, engine, new_used,</span>
<span id="cb30-4">    miles, miles_per_month,</span>
<span id="cb30-5">    price, price_new,</span>
<span id="cb30-6">    depreciation, depreciation_per_month,</span>
<span id="cb30-7">    fuel, transmission,</span>
<span id="cb30-8">    age_in_months</span>
<span id="cb30-9">))</span>
<span id="cb30-10"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">saveRDS</span>(cars, <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">file=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"mazda.rds"</span>)</span></code></pre></div></div>
</div>
<p>Later we can re-hydrate the <code>cars</code> tibble in another notebook with a call to <code>readRDS</code>.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb31" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb31-1">cars <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">&lt;-</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">readRDS</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"mazda.rds"</span>)</span></code></pre></div></div>
<section id="assumptions-made" class="level3">
<h3 class="anchored" data-anchor-id="assumptions-made">Assumptions Made</h3>
<p>We have succeeded in extracting information from a small number of descriptive columns (<code>spec</code> and <code>variant_detail</code>) into a larger number of factor columns. We should find it easier to work with these new columns but a number of assumptions have been made in our processing.</p>
<ol type="1">
<li>We identified a New car as a vehicle that had zero miles and either a “full manufacturer warranty” statement in the <code>spec</code> column or we determined its age to be zero.</li>
<li>We looked for a couple of different formats of registration plate or year in the <code>spec</code> column and rejected vehicles which didn’t match either of these patterns.</li>
<li>Our <code>age_in_months</code> and <code>age_in_months_from_year</code> functions makes use of a table that will date with time. We ought to be able to do better than this.</li>
<li>We have hardwired new prices from the Mazda website into our function that calculates the new price of a vehicle. Some of the older vehicles in our data set may have had a different price when new and also may have expensive extras such as custom paint colours that would have added to their new price. We have ignored that complexity.</li>
</ol>
</section>
<section id="determination-of-per-month-depreciation-and-mileage" class="level3">
<h3 class="anchored" data-anchor-id="determination-of-per-month-depreciation-and-mileage">Determination of Per Month Depreciation and Mileage</h3>
<p>There are several approximations used in the determination of the per month depreciation and mileage.</p>
<p>To estimate depreciation of a vehicle we simply subtract the vehicle price from our estimate of its new price. However, for cars that are new or nearly new and which have some expensive extras it is sometimes possible for the asking price to be greater than our estimated new price. In that situation we set the depreciation to zero.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb32" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb32-1">depreciation <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">if_else</span>(price_new <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> price, price_new <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">-</span> price, <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">0</span>),</span></code></pre></div></div>
<p>To calculate the per month depreciation or mileage we need an estimate of how old the vehicle is. The only information that we have about the age of the vehicle comes from its registration number or registration year. For some vehicles we have the registration number, for others we have the registration year. The two digit age identifier from the registration number gives us a 6 month window in which we know that the car was registered. The vehicle registration year gives us a 12 month window in which we know that the vehicle was registered. So, which of these two we have for a particular vehicle, determines how accurately we can estimate its age - to within 6 months or within 12 months.</p>
<p>We also need to make an assumption about where in the range of 6 or 12 months the vehicle is likely to be. We make the assumption that the age of a vehicle falls in the middle of whichever kind of range (6 or 12 months) we have for the vehicle. The variable <code>mid_age_in_months</code> contains this information and we use that to calculate depreciation_per_month and miles_per_month.</p>
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb33" style="background: #f1f3f5;"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb33-1">mid_age_in_months <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">if_else</span>(</span>
<span id="cb33-2">    <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">!</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">is.na</span>(reg),</span>
<span id="cb33-3">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">age_in_months</span>(reg)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">3</span>,</span>
<span id="cb33-4">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">age_in_months_from_year</span>(spec)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">+</span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">6</span></span>
<span id="cb33-5">)</span>
<span id="cb33-6">...</span>
<span id="cb33-7">depreciation_per_month <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> depreciation <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> mid_age_in_months</span>
<span id="cb33-8">miles_per_month <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span> miles <span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/</span> mid_age_in_months</span></code></pre></div></div>
<p>So, in the absence of the full set of data, we have to make some big assumptions - but they don’t seem unreasonable ones.</p>
<p>The next task is to use the data in the tibble to learn something about the depreciation of these vehicles over time.</p>
<p>Next: <a href="../../../../notebooks/posts/car_prices/02.visualisation/visualisation.html">Mazda CX-30 Price Data - Visualisation</a></p>


</section>

 ]]></description>
  <category>R</category>
  <category>Car Price</category>
  <category>Mazda CX-30</category>
  <guid>https://www.oldgang.net/notebooks/posts/car_prices/01.preparation/preparation.html</guid>
  <pubDate>Mon, 03 Apr 2023 00:00:00 GMT</pubDate>
</item>
<item>
  <title>Car Price Data - Introduction</title>
  <link>https://www.oldgang.net/notebooks/posts/car_prices/car_prices.html</link>
  <description><![CDATA[ 




<p>Understanding what factors affect the depreciation in the value of a car can help to determine the best vehicle to purchase and to give an indication of how much depreciation to expect for a particular configuration of vehicle.</p>
<p>In these notebooks I attempt to understand what drives the used car price of a Mazda CX-30 in the UK using car price data collected in a spreadsheet. The first task is to convert the data from its rough format into one that is suitable for analysis with <a href="https://www.r-project.org">R</a>.</p>
<p>Code is developed in R to first clean and prepare the data and then to examine it using a combination of data plots and tables. Linear regression and regression tree models are then fitted to the data to give numerical estimates of how much vehicle specifications contribute to their depreciation.</p>
<p>Heavy use is made of the opinionated collection of R packages known as the <a href="https://www.tidyverse.org">Tidyverse</a> which make for a more enjoyable and consistent programming experience.</p>
<table class="caption-top table">
<thead>
<tr class="header">
<th>Related Notebooks</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><a href="../../../notebooks/posts/car_prices/01.preparation/preparation.html">Car Price Data - Preparation</a></td>
</tr>
<tr class="even">
<td><a href="../../../notebooks/posts/car_prices/02.visualisation/visualisation.html">Car Price Data - Visualisation</a></td>
</tr>
<tr class="odd">
<td><a href="../../../notebooks/posts/car_prices/03.modelling/modelling.html">Car Price Data - Modelling</a></td>
</tr>
<tr class="even">
<td><a href="../../../notebooks/posts/car_prices/04.tabulation/tabulation.html">Car Price Data - Tabulation</a></td>
</tr>
</tbody>
</table>



 ]]></description>
  <category>R</category>
  <category>Car Price</category>
  <guid>https://www.oldgang.net/notebooks/posts/car_prices/car_prices.html</guid>
  <pubDate>Sun, 02 Apr 2023 00:00:00 GMT</pubDate>
</item>
</channel>
</rss>
