【问题标题】:Why these two formulas give two different correlograms?为什么这两个公式给出两个不同的相关图?
【发布时间】:2021-09-12 17:43:21
【问题描述】:

我正在尝试为包含数字变量和布尔变量(真、假)并有一些缺失值的数据框(名为“df”)计算相关矩阵。

DF 就像

df <- data.frame(
idcode = c(1:10),
contract = c ("TRUE", "FALSE", "FALSE", "FALSE", NA, NA, "TRUE", "TRUE", 
"FALSE", "TRUE"),
score = c (1.17, 5, 7.2, 6.6, 3, 3.8, 7.2, 9.1, 5.4, 2.21),
CEO = c("FALSE", 
NA,"TRUE","TRUE","TRUE","TRUE","TRUE","TRUE","TRUE","TRUE"))

我找到了两种类似的替代方法来计算它,但它们给出了不同的结果:

data.matrix(df) %>% cor(use="pairwise.complete.obs") %>% round(digit=3)

model.matrix(~0+., data=df) %>% cor(use="pairwise.complete.obs") %>% round(digit=3)

谁能解释一下为什么这两个相关矩阵不同,在这种情况下计算相关矩阵的正确方法是什么?

例如,为什么 CEO-Score 对的相关性不同?

【问题讨论】:

  • 您的编辑改进了问题,但我们无法运行您的代码:我们没有df。您能否包含生成df 的代码,并显示结果矩阵的差异?

标签: r correlation


【解决方案1】:

model.matrixdata.matrix 这两个函数在几个方面表现不同,包括如果有 NA 值会发生什么,以及如何处理非数字变量。请参阅帮助页面。

默认情况下,当使用model.matrix 时,在存在NA 的情况下会删除整行。在data.matrix 中,这些被保留并有助于cor(use = "pairwise.complete.obs") 观察,如果不是整行都是NA。这解释了不同的相关系数。

如果您必须使用model.matrix,您可以设置选项以传递NA 值(参见解决方案here)并在cor(use="pairwise.complete.obs") 中处理NA 值。

获取数据

library(tidyverse)

df <- data.frame(
  idcode = c(1:10),
  contract = c(TRUE,FALSE,FALSE,FALSE,NA,NA,TRUE,TRUE,FALSE,TRUE),
  score = c (1.17, 5, 7.2, 6.6, 3, 3.8, 7.2, 9.1, 5.4, 2.21),
  CEO = c(FALSE,NA,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE))

注意,逻辑变量的编码应该不带“”,但结果在这里看起来是一样的。

model.matrix 的默认行为

如果有 NA 值,model.matrix 删除整行,而 data.matrix 保留它们。这是由于默认的options()$na.action 设置为na.omit 并且只影响model.matrix

options()$na.action
#[1] "na.omit"

model.matrix(~0 + ., data = df)
#>    idcode contractFALSE contractTRUE score CEOTRUE
#> 1       1             0            1  1.17       0
#> 3       3             1            0  7.20       1
#> 4       4             1            0  6.60       1
#> 7       7             0            1  7.20       1
#> 8       8             0            1  9.10       1
#> 9       9             1            0  5.40       1
#> 10     10             0            1  2.21       1
#> attr(,"assign")
#> [1] 1 2 2 3 4
#> attr(,"contrasts")
#> attr(,"contrasts")$contract
#> [1] "contr.treatment"
#> 
#> attr(,"contrasts")$CEO
#> [1] "contr.treatment"

data.matrix(df)
#>       idcode contract score CEO
#>  [1,]      1        2  1.17   1
#>  [2,]      2        1  5.00  NA
#>  [3,]      3        1  7.20   2
#>  [4,]      4        1  6.60   2
#>  [5,]      5       NA  3.00   2
#>  [6,]      6       NA  3.80   2
#>  [7,]      7        2  7.20   2
#>  [8,]      8        2  9.10   2
#>  [9,]      9        1  5.40   2
#> [10,]     10        2  2.21   2

na.action = "na.pass"

的行为
# set na.action options
oldpar <- options()$na.action
options(na.action ="na.pass")

model.matrix(~0 + ., data = df)
#>    idcode contractFALSE contractTRUE score CEOTRUE
#> 1       1             0            1  1.17       0
#> 2       2             1            0  5.00      NA
#> 3       3             1            0  7.20       1
#> 4       4             1            0  6.60       1
#> 5       5            NA           NA  3.00       1
#> 6       6            NA           NA  3.80       1
#> 7       7             0            1  7.20       1
#> 8       8             0            1  9.10       1
#> 9       9             1            0  5.40       1
#> 10     10             0            1  2.21       1
#> attr(,"assign")
#> [1] 1 2 2 3 4
#> attr(,"contrasts")
#> attr(,"contrasts")$contract
#> [1] "contr.treatment"
#> 
#> attr(,"contrasts")$CEO
#> [1] "contr.treatment"

data.matrix(df)
#>       idcode contract score CEO
#>  [1,]      1        2  1.17   1
#>  [2,]      2        1  5.00  NA
#>  [3,]      3        1  7.20   2
#>  [4,]      4        1  6.60   2
#>  [5,]      5       NA  3.00   2
#>  [6,]      6       NA  3.80   2
#>  [7,]      7        2  7.20   2
#>  [8,]      8        2  9.10   2
#>  [9,]      9        1  5.40   2
#> [10,]     10        2  2.21   2

比较相关系数

data.matrix(df) %>% cor(use="pairwise.complete.obs") %>% round(digit=3)
#>          idcode contract  score    CEO
#> idcode    1.000    0.312  0.177  0.625
#> contract  0.312    1.000 -0.226 -0.354
#> score     0.177   -0.226  1.000  0.548
#> CEO       0.625   -0.354  0.548  1.000

model.matrix(~0+., data=df) %>% cor(use="pairwise.complete.obs") %>% round(digit=3)
#>               idcode contractFALSE contractTRUE  score CEOTRUE
#> idcode         1.000        -0.312        0.312  0.177   0.625
#> contractFALSE -0.312         1.000       -1.000  0.226   0.354
#> contractTRUE   0.312        -1.000        1.000 -0.226  -0.354
#> score          0.177         0.226       -0.226  1.000   0.548
#> CEOTRUE        0.625         0.354       -0.354  0.548   1.000

请注意,这两个函数处理逻辑变量数据的方式不同(model.matrixcontract 创建了两个虚拟变量,为 CEO 创建了一个虚拟变量(参见 cmets 中的讨论此答案的部分),data.matrix 创建单个二进制整数变量),这反映在相关矩阵中。

重置默认选项

options(na.action = oldpar)

会话信息

sessionInfo()
#> R version 4.1.1 (2021-08-10)
#> Platform: x86_64-apple-darwin17.0 (64-bit)
#> Running under: macOS Catalina 10.15.7
#> 
#> Matrix products: default
#> BLAS:   /Library/Frameworks/R.framework/Versions/4.1/Resources/lib/libRblas.0.dylib
#> LAPACK: /Library/Frameworks/R.framework/Versions/4.1/Resources/lib/libRlapack.dylib
#> 
#> locale:
#> [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
#> 
#> attached base packages:
#> [1] stats     graphics  grDevices utils     datasets  methods   base     
#> 
#> loaded via a namespace (and not attached):
#>  [1] knitr_1.33      magrittr_2.0.1  rlang_0.4.11    fastmap_1.1.0  
#>  [5] fansi_0.5.0     stringr_1.4.0   styler_1.5.1    highr_0.9      
#>  [9] tools_4.1.1     xfun_0.25       utf8_1.2.2      withr_2.4.2    
#> [13] htmltools_0.5.2 ellipsis_0.3.2  yaml_2.2.1      digest_0.6.27  
#> [17] tibble_3.1.4    lifecycle_1.0.0 crayon_1.4.1    purrr_0.3.4    
#> [21] vctrs_0.3.8     fs_1.5.0        glue_1.4.2      evaluate_0.14  
#> [25] rmarkdown_2.10  reprex_2.0.1    stringi_1.7.4   compiler_4.1.1 
#> [29] pillar_1.6.2    backports_1.2.1 pkgconfig_2.0.3

reprex package (v2.0.1) 于 2021-09-19 创建

【讨论】:

  • 您将列视为字符而不是逻辑。那应该使两者具有相同的结果
  • 您好,谢谢!我只是将它们更改为逻辑,但这两个函数仍然以不同的方式处理它们(model.matrix 从一个逻辑变量创建两个虚拟变量,而 data.matrix 将逻辑视为二进制)。
  • 再次检查。当你有一个逻辑变量时,它已经是 0, 1 所以不会创建两个虚拟变量。例如,为什么你有 CEO TRUE 但没有 CEO FALSE 却同时有 contract TRUE 和 contract FALSE 列?
  • 嗨奥尼亚布。我现在明白为什么它很奇怪了,一个逻辑(合同)给出了两个虚拟变量,而另一个(CEO)没有。但我再次检查,结果相同(毕竟这是一个代表例子)。我不知道为什么会这样,你知道吗?也许你可以再检查一次?
最近更新 更多