The letter R here names the language. It does not mean a return variable or the regression goodness-of-fit statistic R-squared.
Start with an ordered vector
c() combines values, <- assigns an object to a name, and ordinary arithmetic can operate element by element. This vectorisation makes a whole sequence of calculations readable without writing a loop. These basic operations are documented in Vectors and assignment.Suppose an asset has fictional prices of USD 100, 110 and 99 at three consecutive observations. There are no dividends, fees or missing observations. Prices are in chronological order, and the two holding periods have equal length. The simple price return for each period is the ending price divided by its preceding price, minus one.
prices <- c(100, 110, 99)
stopifnot(length(prices) >= 2, all(is.finite(prices)), all(prices > 0))
returns <- prices[-1] / prices[-length(prices)] - 1
print(round(returns, 4))
# [1] 0.1 -0.1
print(round(prod(1 + returns) - 1, 4))
# [1] -0.010.1 means +10%, and -0.1 means −10%. prices[-1] drops the first observation, leaving 110 and 99; prices[-length(prices)] drops the last, leaving 100 and 110. The matching positions therefore represent the two adjacent periods. Both vectors have the same length. The code creates returns without changing prices.The combined return is −1%, because the growth factors multiply: . Adding the two percentage returns would hide the loss.
Three semantics worth checking
prices[1] selects the first value. Negative indices exclude positions; they do not count backward from the end. See the official extraction rules.print(c(1, 2, 3, 4) + c(10, 20))
# [1] 11 22 13 24NA marks an unavailable value. For example, the default arithmetic mean propagates it, while na.rm = TRUE explicitly removes it:observed_returns <- c(0.02, NA, 0)
print(mean(observed_returns))
# [1] NA
print(mean(observed_returns, na.rm = TRUE))
# [1] 0.01mean() reference documents its default and missing-value option.Running the analysis again
set.seed() before drawing values. This example uses only base R and no randomness; its code was executed with R 4.5.1. Decimal output is rounded for display because floating-point arithmetic need not represent decimal fractions exactly.Sources
- R Core, An Introduction to R: sections 1.1–1.3, 2.1–2.2, 2.5, 2.7 and Appendix B.4. The current release manual read identifies itself as R 4.6.1; the executed runtime was R 4.5.1.
- R base, Extract or Replace Parts of an Object: vector extraction and negative indices.
- R base, Arithmetic Operators: elementwise arithmetic and recycling.
- R base, Arithmetic Mean: the
na.rmargument and its default. - R base, Random Number Generation: specifying seeds for reproducibility.