You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R语言中cor()函数计算相关矩阵时自定义游说支出占比变量返回NaN的原因及修复方案

问题分析与解决方案

咱们来拆解你遇到的两个核心问题:cor()函数的警告提示,以及自定义变量相关系数全为NaN的异常。

1. 警告信息的根源

你的cor()函数调用写法出现了错误:

cor(join_df, use = "pairwise.complete.obs"[sapply(join_df, is.numeric)])

这里的问题在于:sapply(join_df, is.numeric)会返回一个和数据框列数等长的逻辑向量,用它去索引字符串"pairwise.complete.obs"时,会生成一个长度匹配列数的向量(TRUE对应取字符串第一个字符,FALSE对应NA),但cor()的use参数只接受单个合法字符串(比如"pairwise.complete.obs"、"complete.obs"),这就触发了警告,且函数只会取向量的第一个元素来执行。

你想要实现的是仅对数值型列计算相关矩阵,正确的做法是先筛选出数值型列,再传入cor():

# base R写法
numeric_cols <- sapply(join_df, is.numeric)
cor_matrix <- cor(join_df[, numeric_cols], use = "pairwise.complete.obs")

# 或者用dplyr更简洁的写法
library(dplyr)
numeric_df <- join_df %>% select(where(is.numeric))
cor_matrix <- cor(numeric_df, use = "pairwise.complete.obs")

2. 自定义变量相关系数全为NaN的排查方向

你已经验证过lobby_revt_pct和lobby_gp_pct的计算结果正确,但cor()返回全NaN,大概率是这两个变量存在以下情况:

  • 存在大量Inf值:如果revt或gp为0,那么expend/(revt*1000000)会得到Inf(当expend>0时),cor()无法处理无穷值,会返回NaN。可以用以下代码检查:
    sum(is.infinite(join_df$lobby_revt_pct))
    sum(is.infinite(join_df$lobby_gp_pct))
    
  • 变量自身方差为0:如果某列所有非NA值完全相同,cor()计算时会因方差为0(分母为0)返回NaN。验证方法:
    var(join_df$lobby_revt_pct, na.rm = TRUE)
    var(join_df$lobby_gp_pct, na.rm = TRUE)
    
  • 与其他变量无共同非NA观测:虽然你用了pairwise.complete.obs,但如果自定义变量和所有其他变量的观测对都至少有一个NA,也会返回NaN,可以检查非NA行数确认:
    sum(!is.na(join_df$lobby_revt_pct))
    sum(!is.na(join_df$lobby_gp_pct))
    

修正后的完整代码示例

结合上面的修正,规范后的代码可以写成这样:

library(dplyr)

# 合并数据集
join_df <- left_join(compustat, lobby_expenditure, by = c("gvkey", "year"))

# 计算衍生变量(用mutate更规范易读)
join_df <- join_df %>%
  mutate(
    lobby_revt_pct = (expend / (revt * 1e6)) * 100,
    lobby_gp_pct = (expend / (gp * 1e6)) * 100
  )

# 筛选数值型列并计算相关矩阵
numeric_df <- join_df %>% select(where(is.numeric))
cor_matrix <- cor(numeric_df, use = "pairwise.complete.obs")

内容的提问来源于stack exchange,提问作者kadaktu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 16:57:49