In base R, we split by the Year, loop over the list with lapply, create the model with lm and store the output as a list
out <- lapply(split(df1, df1$Year), function(x)
lm(ln_W ~ Exp, data = x))
NOTE: This doesn't require any packages
Or another option is lmList from lme4
library(lme4)
lmList(ln_W ~Exp | Year, data = df1)
#Call: lmList(formula = ln_W ~ Exp | Year, data = df1)
#Coefficients:
# (Intercept) Exp
#2010 3.7 -0.08
#2011 2.3 NA
#2012 2.5 NA
#2013 2.5 NA
#Degrees of freedom: 5 total; -3 residual
#Residual standard error: 0
data
df1 <- structure(list(Id = c(1L, 1L, 2L, 3L, 3L), ln_W = c(2.5, 2.3,
2.1, 2.5, 2.5), Year = c(2010L, 2011L, 2010L, 2012L, 2013L),
Exp = c(15L, 16L, 20L, 17L, 18L)), class = "data.frame",
row.names = c(NA,
-5L))