理想是这样的:
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)
您可以使用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.