在相关矩阵中,我希望摆脱那些基本上包含与另一行相同的信息的行,除了 var1和var2列中的“ A”和“ B”分别包含“ B”和“ A”
var1 var2 value
1 cyl mpg -0.8521620
2 disp mpg -0.8475514
3 wt mpg -0.8676594
4 mpg cyl -0.8521620
5 disp cyl 0.9020329
6 hp cyl 0.8324475
7 vs cyl -0.8108118
8 mpg disp -0.8475514
9 cyl disp 0.9020329
10 wt disp 0.8879799
11 cyl hp 0.8324475
12 mpg wt -0.8676594
13 disp wt 0.8879799
14 cyl vs -0.8108118
在这里,我们可以在第4行中删除mpg vs cyl,因为在第1行中已经有了cyl vs mpg
我知道我可以过滤列值中的唯一值,但是我不想这样做,因为我的庞大数据集实际上有可能获得多对列的相同相关分数。因此,必须通过匹配名称var1
和var2
到目前为止,我有这段代码可以过滤出超出某个相关值但不是1(变量vs本身)的数据行
mtcars %>%
as.matrix %>%
cor %>%
as.data.frame %>%
rownames_to_column(var = 'var1') %>%
gather(var2, value, -var1) %>%
filter(value > 0.8 | value < -0.8) %>%
filter(value != 1)
编辑
安德烈的答案
cor %>% {(function(x){x[upper.tri(x)]<-NA; x})(.)} %>%
更快,但是Rui的答案更为通用,可以应用于除cor矩阵计算以外的其他情况。
Unit: milliseconds
expr min lq mean median uq max neval cld
Andre 4.818793 5.113676 5.630160 5.408955 5.704825 22.33730 100 a
Rui 5.413692 5.761669 7.531146 6.003656 6.583750 78.02836 100 b
答案 0 :(得分:4)
代码:
mtcars %>%
as.matrix %>%
cor %>% {(function(x){x[upper.tri(x)]<-NA; x})(.)} %>%
as.data.frame %>%
rownames_to_column(var = 'var1') %>%
gather(var2, value, -var1) %>%
filter(value > 0.8 | value < -0.8) %>%
filter(value != 1)
结果:
# var1 var2 value
#1 cyl mpg -0.8521620
#2 disp mpg -0.8475514
#3 wt mpg -0.8676594
#4 disp cyl 0.9020329
#5 hp cyl 0.8324475
#6 vs cyl -0.8108118
#7 wt disp 0.8879799
使用的技巧:
{
包裹在匿名函数周围,以防止默认的管道行为(将管道移至第一个可能的位置),似乎无需此步骤即可工作,但我觉得这样做更安全。 READ MORE ?upper.tri
)(您甚至可以在该步骤中删除对角线,以删除最后一个代码段filter(value != 1)
)我的建议:
mtcars %>%
as.matrix %>%
cor %>% {(function(x){x[upper.tri(x, diag = T)]<-NA; x})(.)} %>%
as.data.frame %>%
rownames_to_column(var = 'var1') %>%
gather(var2, value, -var1) %>%
filter(value > 0.8 | value < -0.8)
答案 1 :(得分:2)
另一种方法就是filter
之前var1 < var2
。
mtcars %>%
as.matrix %>%
cor %>%
as.data.frame %>%
rownames_to_column(var = 'var1') %>%
gather(var2, value, -var1) %>%
filter(value > 0.8 | value < -0.8) %>%
filter(value != 1) %>%
filter(var1 < var2)
# var1 var2 value
#1 cyl mpg -0.8521620
#2 disp mpg -0.8475514
#3 cyl disp 0.9020329
#4 cyl hp 0.8324475
#5 mpg wt -0.8676594
#6 disp wt 0.8879799
#7 cyl vs -0.8108118
答案 2 :(得分:1)
使用 base :
x <- cor(mtcars)
x[ upper.tri(x, diag = TRUE) | abs(x) < 0.8 ] <- NA
na.omit(data.frame(as.table(x)))
# Var1 Var2 Freq
# 2 cyl mpg -0.8521620
# 3 disp mpg -0.8475514
# 6 wt mpg -0.8676594
# 14 disp cyl 0.9020329
# 15 hp cyl 0.8324475
# 19 vs cyl -0.8108118
# 28 wt disp 0.8879799
与接受的整洁答案相比:
microbenchmark::microbenchmark(
base = {
x <- cor(mtcars)
x[ upper.tri(x, diag = TRUE) | abs(x) < 0.8 ] <- NA
na.omit(data.frame(as.table(x)))
},
tidy = {
mtcars %>%
as.matrix %>%
cor %>% {(function(x){x[upper.tri(x, diag = T)]<-NA; x})(.)} %>%
as.data.frame %>%
rownames_to_column(var = 'var1') %>%
gather(var2, value, -var1) %>%
filter(value > 0.8 | value < -0.8)
})
# Unit: microseconds
# expr min lq mean median uq max neval
# base 683.994 718.1025 790.9333 750.099 796.2825 2288.63 100
# tidy 3278.397 3405.3260 3660.0932 3488.334 3676.3870 10212.20 100