1
$\begingroup$

My friend is working on his Sociology Thesis and is currently waiting for the researchers to finish running their experiments and collecting the data that will be used in his project (socio-demographic information is being collected on a group of students and they want to see if a model can be used to predict exam grades). In the meantime, he is trying to learn more about statistical modelling (he has taken a few undergraduate courses in statistics).

He has tried to do some tutorials with regression models that use the famous "iris" and "mtcars" datasets, but he is now interested in "playing" with some data that is "bigger in size" and has some "interesting correlations".

I told him that he can make his own dataset using the "rnorm" functions in R:

var_1 = rnorm(10000,10,2)
var_2 = rnorm(10000,10,2)
var_3 = rnorm(10000,10,2)
response = rnorm(10000,10,2)

my_data = data.frame(var_1, var_2, var_3, response)

But this data is completely random as each variable is fully independent from all other variables, and likely will have no interesting correlation patterns. I thought about this for a while, and thought that perhaps simulating multivariate normal data might result in a more interesting dataset:

library(mvtnorm)
library(dplyr)
    
n <- 10
A <- matrix(runif(n^2)*2-1, ncol=n) 
s <- t(A) %*% A
            
my_data = MASS::mvrnorm(1000000, mu = c(rnorm(10,10,1)), Sigma = s)
my_data = data.frame(my_data)

col.from <- c("X1",  "X2",  "X3"  ,"X4" , "X5"  ,"X6" , "X7" , "X8",  "X9" , "X10")
col.to <- c("var_1", "var_2", "var_3", "var_4", "var_5", "var_6", "var_7", "var_8", "var_9", "response")
final_data = my_data %>% rename_at(vars(col.from), function(x) col.to)
final_data$id = 1:nrow(final_data)

The final data would now look something like this:

> head(final_data)
      var_1     var_2     var_3     var_4     var_5     var_6     var_7     var_8     var_9  response
1  8.179003  8.352989 13.328778 10.607678 10.516110 10.538968  9.632946  9.118660 10.454155  7.306963
2 12.542606  7.631427 13.004173  9.224194 12.997083 12.891917 10.855087  9.924073 10.032415 10.906942
3  6.997328  5.943299 15.676660 13.233185 10.524290  8.336491  7.228844 12.144641 12.294217  3.891815
4  7.747480  8.585957 13.652961  6.784432 12.656338  6.629946  8.316852 12.267082 10.427168 11.075510
5 10.089921  8.478218  8.633301  7.634859  9.995481  9.617159 10.338438  9.003325 11.906386 10.662914
6 12.676234 10.316849  9.908801  9.263423 11.354570 11.729223 12.009226  9.678258  9.442237 12.129947

My Question: Can someone please comment on what I have done? Are there any standard methods that researchers use for simulating datasets that are not "completely random"?

Thanks!

Note: If this approach makes sense, he can obviously change the ranges and covariances of the variables as necessary (e.g. make sure that exam grades have the correct logical ranges)

$\endgroup$
3
  • $\begingroup$ there are different data generation methodologies depending on the objective of data. ie if used for classification/clustering (mixture data), linear/curve modelling, panel/longitudinal data/time series, geospatial etc. All these objectives lead to a certain way of data generation. Ask yourself what you want then look for ways to generate that. $\endgroup$
    – onyambu
    Jun 21 at 6:39
  • $\begingroup$ It's not clear what qualifies as "interesting". If he just wants data of a certain size with some correlations, what you did should be fine. "Realistic data" are not usually perfectly normal (note that $x$-variables in regression can have all kinds of distributions even still in line with assumptions), and dependencies may be nonlinear, also some variables may influence the $y$ very strongly and others very weakly or not at all, but trying to simulate such data may not necessarily be worth the effort in this case. $\endgroup$ Jun 21 at 9:29
  • $\begingroup$ What is "realistic" depends on the field and the meaning of data, and if you really wanted to simulate "realistic data", the first step would be to look at some real data in the field of interest and see how they look like. $\endgroup$ Jun 21 at 9:32

1 Answer 1

2
$\begingroup$

You can simulate the relationships between the variables more explicitly by using linear models for each of the variables. Note that this way you could also simulate categorical variables by using rbinom() or sample().

# Number of observations
n <- 10000
var_1 <- rnorm(n)
# var_2 is associated with var_1 according to the following linear model
var_2 <- rnorm(n, mean = 1 + 0.5 * var_1, sd = 0.5)
# var_3 is a dummy variable indicating the level of a categorical variable
var_3 <- rbinom(n, size = 1, prob = 0.6)
# The response is associated with all three variables
response <- rnorm(n, 2 + 3 * var_1 - 1 * var_2 + 0.5 * var_3, sd = 2)

df <- data.frame(var_1, var_2, var_3, response)
# Check the paired relationships of your simulated data
pairs(df)

You can now try fitting models to these data:

model <- lm(response ~ var_1 + var_2 + var_3, data = df)
summary(model)
Call:
lm(formula = response ~ var_1 + var_2 + var_3, data = df)

Residuals:
    Min      1Q  Median      3Q     Max 
-7.3762 -1.3469 -0.0057  1.3455  7.6417 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  2.03141    0.05134   39.57   <2e-16 ***
var_1        2.98669    0.02813  106.19   <2e-16 ***
var_2       -0.98130    0.04025  -24.38   <2e-16 ***
var_3        0.42529    0.04048   10.51   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 1.989 on 9996 degrees of freedom
Multiple R-squared:  0.624, Adjusted R-squared:  0.6239 
F-statistic:  5530 on 3 and 9996 DF,  p-value: < 2.2e-16

Note how the estimated coefficients are close to the ones specified in the linear model for simulated response variable.

$\endgroup$

Not the answer you're looking for? Browse other questions tagged or ask your own question.