I looked into why the coefficients differ in Gabor's example and it's because the example mistakenly switched the order of x and y. The syntax is roll::roll_lm(x, y), which is the same as fastLm, but the example accidentally switched them. After correcting the example, the coefficients are all equal for lm, fastLm, and roll_lm: library(xts) library(RcppArmadillo) library(roll) set.seed(1) z <- xts(matrix(rnorm(10), ncol = 2), seq(as.Date("2016-08-15"), by = "day", length.out = 5)) colnames(z) <- c("y", "x") fastLm <- rollapplyr(z, width = 4, function(x) coef(fastLm(cbind(1, x[ , 2]), x[ , 1])), by.column = FALSE) colnames(fastLm) <- c("(Intercept)", "x") lm <- rollapplyr(z, width = 4, function(x) coef(lm(y ~ x, data = as.data.frame(x))), by.column = FALSE) colnames(lm) <- c("(Intercept)", "x") roll_lm <- roll_lm(z[ , 2], z[ , 1], 4)$coefficients all.equal(lm, fastLm) # [1] TRUE all.equal(lm, roll_lm) # [1] TRUE [[alternative HTML version deleted]]