我有这样一张桌子:
A B C D E
7 1 6 8 7
9 3 9 5 9
4 6 2 1 10
10 5 3 4 1
1 3 5 9 3
6 4 8 7 6
Run Code Online (Sandbox Code Playgroud)
我正在查找每个变量与表中每个其他变量的相关性.这是我使用的R代码:
test <- read.csv("D:/AB/test.csv")
iterations <- ncol(test)
correlation <- matrix(ncol = 3 , nrow = iterations * iterations)
for (k in 1:iterations) {
for (l in 1:iterations){
corr <- cor(test[,k], test[,l])
corr_string_A <- names(test[k])
corr_string_B <- names(test[l])
correlation[l + ((k-1) * iterations),] <- rbind(corr_string_A, corr_string_B, corr)
}
}
Run Code Online (Sandbox Code Playgroud)
以下是我收到的输出:
Var1 Var2 value
1 A A 1.00000000
2 B A 0.50018605
3 C A -0.35747393
4 D A -0.25670054
5 E A -0.02974821
6 A B 0.50018605
7 B B 1.00000000
8 C B 0.56070716
9 D B 0.46164928
10 E B 0.16813991
11 A C -0.35747393
12 B C 0.56070716
13 C C 1.00000000
14 D C 0.52094589
15 E C 0.23190036
16 A D -0.25670054
17 B D 0.46164928
18 C D 0.52094589
19 D D 1.00000000
20 E D -0.39223227
21 A E -0.02974821
22 B E 0.16813991
23 C E 0.23190036
24 D E -0.39223227
25 E E 1.00000000
Run Code Online (Sandbox Code Playgroud)
但是,我不希望上三角形的值; 即,不应出现对角线值,并且每个唯一组合应仅出现一次.最终输出应如下所示:
Var1 Var2 value
1 B A 0.50018605
2 C A -0.35747393
3 D A -0.25670054
4 E A -0.02974821
5 C B 0.56070716
6 D B 0.46164928
7 E B 0.16813991
8 D C 0.52094589
9 E C 0.23190036
10 E D -0.39223227
Run Code Online (Sandbox Code Playgroud)
我知道有一些像reshape这样的技术可以实现上面的输出,但是我想让上面的R代码适合并产生上面提到的结果.
我认为第二个for循环中的"n"应该动态改变,这有助于实现这一点.但是我不知道如何使这项工作.
您可以您的相关矩阵转换成3列格式as.data.frame和as.table,然后限制值高于或低于对角线是可以做到的subset.
subset(as.data.frame(as.table(cor(dat))),
match(Var1, names(dat)) > match(Var2, names(dat)))
# Var1 Var2 Freq
# 2 B A -0.02299154
# 3 C A 0.23155350
# 4 D A -0.28036851
# 5 E A -0.05230260
# 8 C B -0.58384036
# 9 D B -0.80175393
# 10 E B 0.00000000
# 14 D C 0.52094589
# 15 E C 0.23190036
# 20 E D -0.39223227
Run Code Online (Sandbox Code Playgroud)
请注意,对于较大的数据集,这应该比单独调用cor变量对更有效,因为它cor是矢量化的,而且显然更少的输入.
如果你真的必须保留循环代码,那么你可以通过对for循环对的一些小改动和一些关于correlation你正在计算的行的书来实现你想要的结果:
iterations <- ncol(test)
correlation <- matrix(ncol = 3 , nrow = choose(iterations, 2))
pos <- 1
for (k in 2:iterations) {
for (l in 1:(k-1)){
corr <- cor(test[,k], test[,l])
corr_string_A <- names(test[k])
corr_string_B <- names(test[l])
correlation[pos,] <- rbind(corr_string_A, corr_string_B, corr)
pos <- pos+1
}
}
Run Code Online (Sandbox Code Playgroud)
但是我真的不建议这种循环解决方案; 最好使用我提供的单线程,然后再处理所有生成的NA值.