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

ast*_*ron 4 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" 
Run Code Online (Sandbox Code Playgroud)

表明A和B完全共线(但不是B和C或A和C).

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

jam*_*wen 12

caret软件包具有执行此操作的功能.它返回一个列表,其列号是彼此的线性组合,以及可以删除的列以解决此问题:

 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
Run Code Online (Sandbox Code Playgroud)

编辑

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

如果您想要列名称:

 lincomb = caret::findLinearCombos(df)
 colnames(df)[lincomb$linearCombos[[1]]]
 ## [1] "B" "A"
Run Code Online (Sandbox Code Playgroud)

编辑

针对多组线性组合的情况的附加编辑.假设您的原始数据框具有多个线性组合实例,您可以使用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"
Run Code Online (Sandbox Code Playgroud)

更新

更新以解决OP评论.如果要过滤掉列以创建没有线性组合的新数据框,则findLinearCombos输出的另一个元素是要删除的内容.

 df[-lincomb$remove]
Run Code Online (Sandbox Code Playgroud)


jos*_*ber 6

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

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

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

sapply(positions, function(x) names(dat)[x])
# row col 
# "A" "B"
Run Code Online (Sandbox Code Playgroud)

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

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

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