理想是这样的:
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列。
答案 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)
您可以将which
与arr.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 }}