我必须进行一个相对复杂的相关性分析,其中总共要检查 150 列与其他 36 列的相关性。我已经针对 36 列针对 30 列完成了此操作,这非常耗时,因为我使用单独的命令函数对 30 列中的每一列进行了分析。 这是我的示例数据集:
df <- structure(list(x1 = c(0.2569, 0.0145896, 0.0369, 0.025986,
0.12569, 0.3695), x2 = c(0.125, 0.04582, 0.2569, 0.256369, 0.25698, 0.1456), x3 = c(0.2584, 0.05698, 0.1258, 0.2569, 0.098563, 0.1569),
y1 = c(21, 36, 25, 10, 36, 5), y2 = c(12, 25, 13, 44, 69,23)), row.names = c(NA, -6L), class = "data.frame")
所以我的真实数据集由 x1,...,x150 和 y1,...,y36 组成。而我的目标是
我唯一的解决方案是此页面中的解决方案: 计算来自不同数据帧的两列之间的 R 相关性 ,但随后我将不得不在我的数据集上运行 150 次。有没有办法循环执行此操作?你怎么能制定呢?不幸的是,循环符号对我来说仍然很抽象。将 y 数据存储在单独的数据集中可能会更好?
这是在同一帧中对
x*
和 y*
变量进行配对的一种方法:
out <- outer(
setNames(nm=grep("^x", names(df), value=TRUE)),
setNames(nm=grep("^y", names(df), value=TRUE)),
FUN = function(a, b) mapply(cor, df[a], df[b]))
out
# y1 y2
# x1 -0.5226603 -0.2180721
# x2 -0.1469443 0.4764507
# x3 -0.6718297 -0.1850078
说明:
grep("^x", names(df), value=TRUE)
将返回(在本例中c("x1","x2","x3")
,所有 x 前导变量名;
setNames(nm=..)
将其转换为命名向量,c(x1="x1",...)
,这有助于将行/列名称添加到结果矩阵;
outer
对两个向量之间的值进行笛卡尔连接,当它调用其函数 (FUN=
) 时,它一次调用它们all。这里使用的函数需要能够处理一个 a
非常长的调用。显然cor
不喜欢那样,所以我们使用mapply
在某种意义上进行矢量化。例如,如果我们调试它,那么在 FUN
函数中,我们会看到
# debug at #1: mapply(cor, df[a], df[b])
a
# x1 x2 x3 x1 x2 x3
# "x1" "x2" "x3" "x1" "x2" "x3"
b
# y1 y1 y1 y2 y2 y2
# "y1" "y1" "y1" "y2" "y2" "y2"
我们需要将该向量转换为数据列表,因此我们使用
[
。 (我在下面使用 as.list
是因为它通常返回一个 data.frame
... 这实际上只是一个具有特殊格式的 list
,但我想强调一下 mapply
只关心获取数据列表。)
as.list(df[a])
# $x1
# [1] 0.2569000 0.0145896 0.0369000 0.0259860 0.1256900 0.3695000
# $x2
# [1] 0.125000 0.045820 0.256900 0.256369 0.256980 0.145600
# $x3
# [1] 0.258400 0.056980 0.125800 0.256900 0.098563 0.156900
# $x1.1
# [1] 0.2569000 0.0145896 0.0369000 0.0259860 0.1256900 0.3695000
# $x2.1
# [1] 0.125000 0.045820 0.256900 0.256369 0.256980 0.145600
# $x3.1
# [1] 0.258400 0.056980 0.125800 0.256900 0.098563 0.156900
和
df[b]
.类似
mapply
所做的是用cor
的第一个元素和df[a]
的第一个元素调用df[b]
,然后用cor
的第二个元素和df[a]
的第二个元素调用df[b]
等
最后,
outer
将其输出格式化为矩阵(命名,因为我们添加了 setNames(nm=...)
;如果您想要它作为三列框架,那很容易:将 as.data.frame.table(...)
: 包裹起来
as.data.frame.table(out)
# Var1 Var2 Freq
# 1 x1 y1 -0.5226603
# 2 x2 y1 -0.1469443
# 3 x3 y1 -0.6718297
# 4 x1 y2 -0.2180721
# 5 x2 y2 0.4764507
# 6 x3 y2 -0.1850078
如果你不喜欢这个名字,那就改吧:
as.data.frame.table(out, responseName='correlation')
# Var1 Var2 correlation
# 1 x1 y1 -0.5226603
# 2 x2 y1 -0.1469443
# 3 x3 y1 -0.6718297
# 4 x1 y2 -0.2180721
# 5 x2 y2 0.4764507
# 6 x3 y2 -0.1850078