I also used to think the weights were a convenient way of encoding sample sizes for repeated observations. But the following example shows that this is not the case for a simple linear model. I first define a contingency table with observed/invented shoe sizes and heights of people and fit a leats squares regression specifying the frequencies as the weights:
SKdata = matrix(c(20,5,5,5,40,15,3,27,30,2,3,10),ncol=4)
dimnames(SKdata) = list(shoesize=10:12,height=seq(160,190,by=10))
x = as.data.frame(as.table(SKdata), stringsAsFactors=FALSE)
for (i in 1:ncol(x)) x[,i] = as.numeric(x[,i])
fit1 = lm(height ~ shoesize,data=x, weights=Freq)
summary(fit1)
Notice that the coefficient for the slope is non significant and the residual error is based on "10 degrees of freedom"
This changes when I convert the contingency table into the "raw" data, meaning one row per observation, with the convenience function expand.dft:
expand.dft <- function(x, na.strings = "NA", as.is = FALSE, dec = ".")
{
DF <- sapply(1:nrow(x), function(i) x[rep(i, each = x$Freq[i]), ],
simplify = FALSE)
DF <- subset(do.call("rbind", DF), select = -Freq)
for (i in 1:ncol(DF))
{
DF[[i]] <- type.convert(as.character(DF[[i]]),
na.strings = na.strings,
as.is = as.is, dec = dec)
}
DF
}
fit2 = lm(height ~ shoesize,data=expand.dft(x))
summary(fit2)
We obtain the identical coefficient but this time highly significant as based on "163 degrees of freedom"