如何在R中删除相关或重复的变量或个体

3
我有以下类型(但变量和ind非常多)的数据:
    mydf <- data.frame (Inv = 1:6, varA = c(1,1,1,  0,1,1),
   varB = c(1,0,1,  0, 1,1), varC = c(1,0,0,  0,1,1), varD = c(1,1,1,  0,1,1), 
     varE = c(1,0,1,  0, 1,1), varF = c(1,1,1,  0, 1,1))

mydf
  Inv varA varB varC varD varE varF
1   1    1    1    1    1    1    1
2   2    1    0    0    1    0    1
3   3    1    1    0    1    1    1
4   4    0    0    0    0    0    0
5   5    1    1    1    1    1    1
6   6    1    1    1    1    1    1

我想进行所有的一对一比较(包括变量和个体/受试者),如果它们重复,则只保留一个,并将重复的个体/变量名称记录在不同的文件中:
例如,在上述数据中:
在变量之间:
varA is exactly same as varD and varF - so I will just keep varA only in new data

mydf$varA == mydf$varE
[1]  TRUE TRUE  TRUE  TRUE  TRUE  TRUE

varB and varE has exactly same data - so I will just keep varB
varC is unique

在Inv(即主题)中:
1, 5 and 6 are same  -> so just keep 1

因此,生成的输出文件为:
        mydf <- data.frame (Inv = 1:4, varA = c(1,1,1,  0),
       varB = c(1,0,1,  0), varC = c(1,0,0,  0))
  Inv varA varB varC
1   1    1    1    1
2   2    1    0    0
3   3    1    1    0
4   4    0    0    0

我可以通过相关矩阵来找到重复。
cor(mydf[,-1])
          varA      varB      varC      varD      varE      varF
varA 1.0000000 0.6324555 0.4472136 1.0000000 0.6324555 1.0000000
varB 0.6324555 1.0000000 0.7071068 0.6324555 1.0000000 0.6324555
varC 0.4472136 0.7071068 1.0000000 0.4472136 0.7071068 0.4472136
varD 1.0000000 0.6324555 0.4472136 1.0000000 0.6324555 1.0000000
varE 0.6324555 1.0000000 0.7071068 0.6324555 1.0000000 0.6324555
varF 1.0000000 0.6324555 0.4472136 1.0000000 0.6324555 1.0000000

我们可以自动化这个过程吗?
4个回答

11

您还可以使用caret软件包中的findCorrelation函数:

findCorrelation(x, cutoff = .90, verbose = FALSE)

输出是一个索引向量,表示要删除的列。


findCorrelation(mydf, cutoff=0.9, verbose=FALSE) 在计算相关性时出现错误:相关矩阵不对称。
- xbsd
@xbsd:回复晚了一点,但第一个参数“x”应该是相关矩阵而不是数据框。在您的情况下,运行findCorrelation(cor(mydf), cutoff=0.9, verbose=FALSE)。 - discipulus

6
这应该能解决问题:
dat <- mydf[-1]
cMat <- abs(cor(dat)) >= (1 - .Machine$double.eps^0.5)
whichKeep <- which(rowSums(lower.tri(cMat) * cMat) == 0)
cbind(mydf[1], mydf[whichKeep + 1])

  Inv varA varB varC
1   1    1    1    1
2   2    1    0    0
3   3    1    1    0
4   4    0    0    0
5   5    1    1    1
6   6    1    1    1

1
感谢您提供的出色解决方案。是否可以列出落在同一组(相关性=1)的变量,以便我们知道被删除的内容及其原因? - jon
1
@hijo。当然可以。像这样的代码可以获取名称:names(dat)[rowSums(lower.tri(cMat) * cMat) > 0] - Josh O'Brien

2

这是一个非常可疑的统计工作,但很容易识别相关矩阵中的元素是1以及哪些在上三角。

cmat <- cor(mydf[,-1])
hicorr <- which(row(cmat) < col(cmat) & cmat==1, arr.ind=TRUE)[,"col"]
hicorr
#varA varB varA varD 
#   4    5    6    6 

mydf[ , -hicorr]
  Inv varA varB varF
1   1    1    1    1
2   2    1    0    1
3   3    1    1    1
4   4    0    0    0
5   5    1    1    1
6   6    1    1    1

1

我了解您正在尝试执行特征选择/降维。在这种情况下,请查看CRAN的FSelector软件包。特别是,有几个基于相关性的过滤器,例如linear.correlation(formula, data)。有关详细信息,请参见this


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接