R中data.matrix与model.matrix计算相关矩阵结果为何不同?
两种代码计算结果存在差异的原因
两个函数对原始数据的预处理逻辑完全不同,是结果不一致的核心原因:
data.matrix()的处理逻辑:- 仅将数据框所有列转换为数值类型,不会删除任何行:字符型的
"TRUE"/"FALSE"会先按字母序转为因子,再映射为整数2/1,缺失值NA会原样保留 - 后续
cor(use="pairwise.complete.obs")计算每对变量的相关系数时,仅剔除这两个变量同时为NA的观测,不同变量对使用的观测样本量可能不同
- 仅将数据框所有列转换为数值类型,不会删除任何行:字符型的
model.matrix()的处理逻辑:- 为线性模型生成设计矩阵时,默认会先删除所有包含任意缺失值的行,你给出的示例数据中,行2(CEO缺失)、行5、行6(contract缺失)会被直接剔除,最终仅保留7行完整观测
- 字符型的
"TRUE"/"FALSE"会被转成0/1哑变量,列名会变为contractTRUE、CEOTRUE这类形式 - 后续计算相关系数时,所有变量对用的都是这7行样本,和前者的样本量完全不同,结果自然有差异
以你提到的CEO与Score的相关系数差异为例:data.matrix路径计算时仅剔除了CEO缺失的第2行,用剩下9行观测计算;model.matrix路径除了第2行,还额外剔除了contract缺失的第5、6行,只用7行观测计算,样本不同结果自然不同。
该场景下的正确计算方法
可根据你的分析需求选择对应方案:
- 如果你希望尽可能保留所有可用观测,按
pairwise.complete.obs逻辑计算相关,建议使用第一种路径,但需提前过滤不需要纳入相关的列(如示例中的idcode是编号,不参与相关计算),并把字符型布尔列转为标准逻辑型避免编码异常,优化代码如下:
# 预处理:删除idcode,将字符布尔列转为逻辑型 df_processed <- df[, !names(df) %in% "idcode"] df_processed$contract <- as.logical(df_processed$contract) df_processed$CEO <- as.logical(df_processed$CEO) # 计算相关矩阵 data.matrix(df_processed) %>% cor(use = "pairwise.complete.obs") %>% round(digits = 3)
- 如果你要求所有相关系数都基于完全相同的完整观测样本(即所有变量都无缺失的行),可以用第二种路径,但建议手动提前删除含缺失值的行,避免model.matrix隐式删行导致的逻辑不透明,代码参考:
# 手动剔除含任意缺失的行,删除idcode后计算 df_complete <- df[complete.cases(df), !names(df) %in% "idcode"] df_complete$contract <- as.logical(df_complete$contract) df_complete$CEO <- as.logical(df_complete$CEO) cor(df_complete, use = "everything") %>% round(digits = 3)
内容的提问来源于stack exchange,提问作者Ludovico
相关产品推荐
相关产品推荐

