lm with 3 constant values

Hello, I have three sets of data:

  1. With two constant values
  2. With three constant values
  3. With four constant values

For each of them, I need to obtain the slope of a linear regression to see their trend. However, for case 2 (3 constant values), the slope is <0 (a very low value, but in practice negative), while for the other two cases, the slope is equal to 0.

I cannot understand the reason for this difference in the cases if the values are constant in all three.

datos_2 <- data.frame(Año = c(2018, 2019), Porc_Satisf = c(100, 100))
datos_3 <- data.frame(Año = c(2017, 2018, 2019), Porc_Satisf = c(100, 100, 100))
datos_4 <- data.frame(Año = c(2017, 2018, 2019,2020), Porc_Satisf = c(100, 100, 100, 100))

lm(Porc_Satisf ~ Año, data = datos_2)  # Resultado limpio
lm(Porc_Satisf ~ Año, data = datos_3)  # Posibles problemas numéricos
lm(Porc_Satisf ~ Año, data = datos_4)  # Resultado limpio

Resultados:

# n = 2
lm(Porc_Satisf ~ Año, data = datos_2)  # Resultado limpio

Call:
lm(formula = Porc_Satisf ~ Año, data = datos_2)

Coefficients:
(Intercept)          Año  
        100            0  

# n = 3
lm(Porc_Satisf ~ Año, data = datos_3)  # Posibles problemas numéricos

Call:
lm(formula = Porc_Satisf ~ Año, data = datos_3)

Coefficients:
(Intercept)          Año  
  1.000e+02   -2.461e-14  

# n = 4
lm(Porc_Satisf ~ Año, data = datos_4)  # Posibles problemas numéricos

Call:
lm(formula = Porc_Satisf ~ Año, data = datos_4)

Coefficients:
(Intercept)          Año  
        100            0  

Regards,

Welcome to Circle 1 of R Inferno - Falling into the Floating Point Trap

If you need to compare floating point numbers (e.g. to check if your model coefficients are 0), you should probably consider comparison with a tolerance, something like isTRUE(all.equal(...)) or dplyr::near(), by default both use sqrt(.Machine$double.eps) = ~1.5e-08 for the tolerance:

z <- -2.4613922385718e-14
isTRUE(all.equal(z, 0))
#> [1] TRUE
dplyr::near(z, 0)
#> [1] TRUE

sqrt(.Machine$double.eps)
#> [1] 1.490116e-08

Short answer: rounding error. Longer answer: floating point arithmetic is not exact.