如何在data.frame中列出完美共线数字向量对?

时间:2016-01-21 16:32:43

标签: r

理想是这样的:

find_all_perfectly_collinear_pairs( data.frame( A = c( 1, 2, 3), 
                                                B = c( 2, 4, 6), 
                                                C = c( 3, 5, 1 ) ) );

     [,1] [,2]
[1,] "A"  "B" 

表示A和B完全共线(但不是B和C或A和C)。

所有预测变量都是仅包含整数的数字向量。查看大约100行25列。

2 个答案:

答案 0 :(得分:11)

df = data.frame( A = c( 1, 2, 3), B = c( 2, 4, 6), C = c( 3, 5, 1 )) caret::findLinearCombos(df) ## $linearCombos ## $linearCombos[[1]] ## [1] 2 1 ## $remove ## [1] 2 包有一个执行此操作的功能。它返回一个列表,其列号是彼此的线性组合,以及可以删除的列以解决此问题:

 lincomb = caret::findLinearCombos(df)
 colnames(df)[lincomb$linearCombos[[1]]]
 ## [1] "B" "A"

修改

根据OPs问题编辑以获取列名作为结果

如果您想要列名:

lapply

修改

针对多组线性组合的情况的附加编辑。假设您的原始数据框有多个线性组合实例,您可以在findLinearCombos

返回的线性组合列表上使用 df = data.frame( A = c( 1, 2, 3), B = c( 2, 4, 6), C = c( 3, 5, 1 ), D = c( 6, 10, 2)) lincomb = caret::findLinearCombos(df) lapply(lincomb$linearCombos, function(x) colnames(df)[x]) ## [[1]] ## [1] "B" "A" ## ## [[2]] ## [1] "D" "C"
findLinearCombos

更新

更新以解决OP评论。如果要过滤掉列以创建没有线性组合的新数据框,则 df[-lincomb$remove] 输出的其他元素将被删除。

{{1}}

答案 1 :(得分:6)

您可以将whicharr.ind=TRUE一起使用以获取足够接近1的相关矩阵的条目,然后您可以将子集分配到相关矩阵对角线下方的条目:

(positions <- subset(as.data.frame(which(cor(dat) > 0.9999, arr.ind=TRUE)), row < col))
#   row col
# A   1   2

如果您想获取变量的名称而不是列号,则可以进行转换:

sapply(positions, function(x) names(dat)[x])
# row col 
# "A" "B"

如果您想在执行线性回归之前从数据框中删除这些列(正如您在问题的评论中所建议的那样),那么您只需执行以下操作:

(dat.smaller <- dat[,-unique(positions$row)])
#   B C
# 1 2 3
# 2 4 5
# 3 6 1

请注意,在这种情况下,实际上并不需要计算列名,并且使用which函数输出的列号实际上更方便{{1 }}