* and / run before + and -. When you want a different order, say so with brackets.
Step 2. Powers and remainders
^ raises a number to a power. Growing 8% a year for three years is 1.08 ^ 3, and the reverse, the annual rate behind three years of 8% total growth, is 1.08 ^ (1 / 3).
print(1.08^3) # -> [1] 1.259712 <- 8% a year for 3 years
[1] 1.259712
print(1.08^ (1/3)) # -> [1] 1.025986 <- 8% over 3 years is 2.6% a year
[1] 1.025986
%% gives the remainder after a division and %/% gives the whole part. Splitting 40 shares into three equal tranches leaves one share over.
print(shares %/%3) # -> [1] 13 <- shares per tranche
[1] 13
print(shares %%3) # -> [1] 1 <- shares left over
[1] 1
print(shares %%2) # -> [1] 0 <- 40 splits evenly in two
[1] 0
A remainder of 0 means the division came out exact.
Step 3. R drops the trailing zeros
The profit is 750.00 in money, but R prints 750. It shows the shortest form of the number and stops there.
profit <- (sell - buy) * shares # 18.75 a share across 40 sharesprint(profit) # -> [1] 750 <- not 750.00
[1] 750
print(profit /7) # -> [1] 107.1429 <- cut short on display
[1] 107.1429
print(round(profit /7, 2)) # -> [1] 107.14
[1] 107.14
round(x, 2) keeps two decimals. It changes the number, not just the display, so use it when you want the value rounded and not before.
I asked for four decimals and got 1.026. round() cannot force a trailing zero, because 1.0260 and 1.026 are the same number. For a fixed number of decimals on screen you need Step 5.
Step 4. The return as a decimal
A return is the sell price over the buy price, minus 1. Store it as a decimal, always. 0.125, not 12.5.
print(ret *100) # -> [1] 12.5 <- the same return in percent
[1] 12.5
print(round(ret *100, 2)) # -> [1] 12.5 <- still not 12.50
[1] 12.5
Decimals are what the arithmetic in later lessons expects: 1 + ret is a growth factor, and 0.125 gives 1.125. Percentages are for the last step, when a person reads the number.
Step 5. Format it with sprintf
sprintf("%.2f", x) builds text from a number with exactly two decimals. The %.2f is a slot: f means a number with decimals and .2 means two of them.
print(sprintf("%.2f", profit)) # -> [1] "750.00"
[1] "750.00"
print(sprintf("%.2f", ret *100)) # -> [1] "12.50"
[1] "12.50"
print(sprintf("%.2f%%", ret *100)) # -> [1] "12.50%"
%% inside the quotes is how you get one literal % on the end, because a single % starts a slot. And the result is "character", text, not a number. Format at the point of printing; do your sums on the numbers.
paste0() glues pieces together with nothing in between.
line <-paste0("bought at ", buy, ", sold at ", sell,", profit ", sprintf("%.2f", profit))print(line) # -> [1] "bought at 150, sold at 168.75, profit 750.00"
[1] "bought at 150, sold at 168.75, profit 750.00"
buy came out as 150 because paste0 converted the number the same way print does. The profit kept its two decimals because sprintf had already turned it into text.
Step 6. print and cat
print shows you the object: a [1] prefix, and quotes around text. cat writes the contents out raw, and adds no line ending of its own, so you supply "\n".
print(line) # -> [1] "bought at 150, sold at 168.75, profit 750.00"
[1] "bought at 150, sold at 168.75, profit 750.00"
cat(line, "\n") # -> bought at 150, sold at 168.75, profit 750.00
bought at 150, sold at 168.75, profit 750.00
cat also puts a space between whatever you pass it, which is why "\n" sits as its own argument.
On a vector the difference is bigger. Three daily returns, stored as decimals and shown as percentages:
rets <-c(0.0125, -0.0038, 0.0207) # three daily returns, as decimalsdays <-c("Tue", "Wed", "Thu") # the day each one belongs toprint(rets) # -> [1] 0.0125 -0.0038 0.0207
I bought 25 shares at 40.00 and sold them at 46.50. Work out the profit and the return, keep the return as a decimal, and print one line reading profit 162.50, return 16.25%.
TipShow answer
buy <-40.00# price paid per sharesell <-46.50# price sold atshares <-25# size of the positionprofit <- (sell - buy) * shares # brackets first, then multiplyret <- sell / buy -1# kept as a decimalprint(profit) # -> [1] 162.5print(ret) # -> [1] 0.1625cat(paste0("profit ", sprintf("%.2f", profit),", return ", sprintf("%.2f%%", ret *100)), "\n")# -> profit 162.50, return 16.25%