I would like to create many(!) examples for exercices, where I would like to control various parameters such as the coefficients, their uncertainty, t-values and p-values of the linear model.
I know, there is a lot of data in the web, but it is really difficult to find appropriate data to a specific question / example and
if you need a new example you need to search the web again and again.
So I thought, I'll create data on my own - but it seems, this is really difficult. What I do not want
- Decrease
n
untilt
-/p
-values improve ("leading to no data") - Increase sigma in
rnorm
untilt
-/p
-values improve ("an overall increase in sigma of a factor of 10 would do the job, but then no linear model is left." See the example below.)
Below you can find what I have using R. Is there a way to "improve" the result? In my concrete case I would like data which
can be checked by plotting the data (about 100 to 1000 points, R's Std Error
small) and p-values
ranging from say 1e-5 to 0.8
.
Edit: Thanks to Mickybo Yakari's answer, the situation improved a lot ($x_i$ values are sampled according to a multivariate gaussion distribution), but it would be great, if I could also "control" the p-values. The example below shows e.g. a Pr(>|t|)
value for (Intercept)
of 0.00016
but I would like this parameter to be more significant.
Is there any way to obtain, what I want?
#' Generate sparse precision matrix (Mickybo Yakari's answer fixed correlations)
#'
#' @param dimension An integer, the number of rows of the precision matrix.
#' @param upper A numeric in (0,1) specifying the range of allowed non-zero entries.
#' @param seed An integer, the random seed.
#'
#' @return A precision matrix
generate.sparse.precision.matrix <- function(dimension, upper, seed) {
matrix <- matrix(rep(0,dimension*dimension), ncol = dimension)
set.seed(seed)
vec <- runif(n = dimension^2, min = 0, max = 1)
for (i in 1:dimension) {
for (j in i:dimension) {
matrix[i,j] <- vec[i + j] # forces symmetry
if ( matrix[i,j] < upper) {
matrix[i,j] <- 0
}
}
}
diag(matrix) <- rep(1, dimension)
# Now we ensure diagonal dominance
for (k in 1:dimension) {
matrix[k,] <- matrix[k,]/sum(abs(matrix[k,]))
}
return(matrix)
}
set.seed(1)
n <- 100
precision <- matrix(c(4, 5, 0.01, # off-diagonal: s_xy <= s_x*s_y
5, 8, 0,
0.01, 0, 6), 3, 3)
mu0 <- c(2, 4, 8)
mat <- MASS::mvrnorm(n = n, mu = mu0,
Sigma = solve(precision),
tol = 1e-8, empirical = TRUE)
lapply(c(1:3), function(i) eval(parse(text = paste0("x", i, " <<- mat[, ", i, "]"))))
y <- 100 - 4*x1 + 3*x2 - 2*x3 + rnorm(n, 0, 5)
df <- data.frame(x1 = x1, x2 = x2, x3 = x3, y = y, stringsAsFactors = FALSE)
plot(df)
par(mfrow = c(1, 2))
boxplot(df[, c(1:3)], names = c("x1", "x2", "x3"))
boxplot(df[, 4], xlab = "y")
par(mfrow = c(1, 1))
corrplot::corrplot(cor(df), type = "upper")
fit <- lm(formula = y ~ x1 + x2 + x3, data = df)
print(summary(fit))
# plenty of space for improvement :-)
In some way related Question: (1)