使用R中的相关矩阵自动删除共线变量

时间:2015-03-07 04:08:24

标签: r for-loop regression correlation

我正在尝试迭代并自动创建基于矩阵相关的独立变量对,然后我将其放入回归模型中以移除对中最不重要的一个。

到目前为止,我的代码看起来像这样:

#Correlation testing on only numeric variables
num.cols <- bind.data[,sapply(bind.data, is.numeric),with=FALSE]
cor.matrix <- cor(num.cols,use="complete.obs")

#Create a table of all pairings of potentially colinear variables
#start the process by hardcoding the first 2 iterations
cor.vars1 <- expand.grid(var1 = colnames(cor.matrix)[1], 
                     var2 = row.names(cor.matrix[which((abs(cor.matrix[,1]) > cor.cutoff) & (abs(cor.matrix[,1]) != 1)),]))
cor.vars1 <- as.data.table(cor.vars1)

cor.vars2 <- expand.grid(var1 = colnames(cor.matrix)[2], 
                     var2 = row.names(cor.matrix[which((abs(cor.matrix[,2]) > cor.cutoff) & (abs(cor.matrix[,2]) != 1)),]))
cor.vars2 <- as.data.table(cor.vars2)
cor.vars <- rbind(cor.vars1, cor.vars2)

#now create for-loop to automatically do the rest
for (i in 3:length(num.cols)) {
  cor.varsn <- expand.grid(var1 = colnames(cor.matrix)[i], 
                       var2 = row.names(cor.matrix[which((abs(cor.matrix[,i]) > cor.cutoff) & (abs(cor.matrix[,i]) != 1)),]))
  cor.vars <- rbind(cor.vars, cor.varsn)
}

基本思想是相关矩阵中的每一列,我想要一个由列名称和变量的每个行名称组成的扩展网格,其中列变量的相关性大于某些截断值&#34; cor.cutoff&#34 ;。我将为每一列做这个并将它们全部绑定。最后,我将得到一个2列data.table,其中每一行代表一组相关的独立预测变量。

我的问题是for循环在到达与其他变量没有相关性的列时会中断。它不是跳到满足要求的下一列,而是完全停止。有没有一种优雅的方式来做到这一点,而不是一个&#34; if&#34;声明?特别是当第一列是问题时(即cor.vars1或cor.vars2与其他变量没有相关性。

1 个答案:

答案 0 :(得分:0)

您可以尝试以下功能:

rmcl = function(cor_mat, threshold) {
  cor_mat = abs(cor_mat)
  stopifnot(sum(cor_mat[is.na(cor_mat)]) == 0) 
  for (i in 1:(nrow(cor_mat) - 1)) {
    for (j in (i+1):ncol(cor_mat)) {
      if(cor_mat[i, j] > threshold) {
        cor_mat[i, ] = rep(NA, ncol(cor_mat))
        break
      }
    }
  }
  idx = which(!is.na(cor_mat[, 1]))
  cor_mat[idx, idx]
}

技巧是保留相关矩阵的形状,以便迭代可以继续。

一个例子:

data = data.frame(x1 = rnorm(100), x2 = rnorm(100), x3 = rnorm(100))
# the last 3 columns are in perfect correlation with the first 3.
data$x4 = 2 * data$x1
data$x5 = 2 * data$x2
data$x6 = 2 * data$x3
c = cor(data)
c = rmcl(c, .9)
c


          x4         x5         x6
x4 1.0000000 0.08847400 0.03297110
x5 0.0884740 1.00000000 0.09915481
x6 0.0329711 0.09915481 1.00000000