Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Automation of multivariate regression with variable transformations

I am working on a regression problem, and I try to make the process more automatic. For each of the x variables I have an X matrix of transformations I would like to test (each column represents a transformation of the x variable). So I need to create a loop that would take one vector from each of the X matrices, test them against the y variable and store t-values of each variable.

I worked it out for 2 X variables, but need your help with scaling it up to n variables. The code is below.

testvars <- function(y,X1,X2) {

  Tvals_X1 = data.frame(matrix(0, ncol = ncol(X2), nrow = ncol(X1)))
  Tvals_X2 = data.frame(matrix(0, ncol = ncol(X2), nrow = ncol(X1)))

  for (i in 1:ncol(X1)) {
    for (j in 1:ncol(X2)) {
      temp <- lm(y ~ X1[,i] + X2[,j])
      Tvals_X1[i,j] <- summary(temp)$coefficients[2,3]
      Tvals_X2[i,j] <- summary(temp)$coefficients[3,3]
    }
  }
}
like image 319
Seva Gumeniuk Avatar asked Nov 26 '25 08:11

Seva Gumeniuk


1 Answers

Here is my approach;

# example datas
set.seed(1); y <- matrix(runif(20), ncol=1)
set.seed(2); x1 <- matrix(runif(60), ncol=3)
set.seed(3); x2 <- matrix(runif(80), ncol=4)
set.seed(4); x3 <- matrix(runif(40), ncol=2)
set.seed(5); x4 <- matrix(runif(60), ncol=3)
I made the matrix having all combination of col-number
col.v <- sapply(list(x1,x2,x3,x4), ncol)         # ncols of each data
col.comb <- expand.grid(sapply(col.v, seq.int))  # its all combinations
# > head(col.comb, n=4)
#   Var1 Var2 Var3 Var4
# 1    1    1    1    1
# 2    2    1    1    1
# 3    3    1    1    1
# 4    1    2    1    1
# 5    2    2    1    1
I got t.value by apply(col.comb, 1, ... )
tval <- apply(col.comb, 1, function(a) { 
  temp <- lm(y ~ x1[,a[1]] + x2[,a[2]] + x3[,a[3]] + x4[,a[4]])
  summary(temp)$coefficients[2:5, 3] })

# > head(tval, n=2)              # tval is matrix
#       x1[, a[1]] x2[, a[2]] x3[, a[3]] x4[, a[4]]
# [1,] -0.05692452 -0.9047370 -0.3758997   1.968530
# [2,]  0.03476527 -0.9260632 -0.3740936   1.965884
I changed tval-matrix's each col into array and combined each array into list.
results <- list()            # results[[1]] is x1's array
for(i in seq.int(length(col.v))) results[[i]] <- array(tval[,i], dim=col.v)
 # names(results) <- c("x1", "x2", "x3", "x4")   # if you want

results2 <- array(t(tval), dim=c(length(col.v), col.v))   # all.array.version
 ## results[[1]] is the same as results2[1,,,,]   # both is x1's array
  # dimnames(results2)[[1]] <- list("x1", "x2", "x3", "x4")   # if you need
check
c(results[[1]][2,3,2,3], results[[2]][2,3,2,3], results[[3]][2,3,2,3], results[[4]][2,3,2,3])
# [1]  0.54580342 -0.56418433 -0.02780492 -0.50140806

c(results2[1,2,3,2,3], results2[2,2,3,2,3], results2[3,2,3,2,3], results2[4,2,3,2,3])
# [1]  0.54580342 -0.56418433 -0.02780492 -0.50140806

summary(lm(y ~ x1[,2] + x2[,3] + x3[,2] + x4[,3]))$coefficients[2:5,3]
#    x1[, 2]     x2[, 3]     x3[, 2]     x4[, 3] 
# 0.54580342 -0.56418433 -0.02780492 -0.50140806   # no problem
function version (n = 4);
testvars2 <- function(y, x1, x2, x3, x4){

  col.v <- sapply(list(x1,x2,x3,x4), ncol)
  col.comb <- expand.grid(sapply(col.v, seq.int))

  tval <- t(apply(col.comb, 1, function(a) { 
    temp <- lm(y ~ x1[,a[1]] + x2[,a[2]] + x3[,a[3]] + x4[,a[4]])
    summary(temp)$coefficients[2:5, 3] }))

  results <- list()
  for(i in seq.int(length(col.v))) results[[i]] <- array(tval[,i], dim=col.v)
  #results2 <- array(t(tval), dim=c(length(col.v), col.v))

  return(results)
}
like image 53
cuttlefish44 Avatar answered Nov 27 '25 21:11

cuttlefish44



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!