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

滑动Spearman相关性分析中p值与估计值不一致问题排查

解决滑动Spearman相关性中相同rho对应不同p值的问题

我来帮你拆解这个反直觉的问题——相同的Spearman相关系数估计值却对应不同p值,核心原因其实和秩结(ties)的校正有关,咱们一步步捋清楚:

1. 为什么相同rho会有不同p值?

你提到经典t分布近似中n和r相同则p值一致,但pspearman::spearman.test的t-distribution近似并不是完全照搬经典公式!这个函数专门针对小样本或多结场景做了优化,在计算t统计量时会根据x和y向量中的秩结数量进行校正。

简单来说:即使两个窗口的rho和样本量n相同,只要窗口内数据的结数(即重复值的数量)不一样,pspearman计算出的t统计量和对应的p值就会不同。

2. 验证这个猜想

你可以在相关性函数中加入结数统计,直接观察差异:

psSpearman <- function(x, y) {
  # 统计x和y中的结数量(重复值组的个数)
  ties_x <- sum(table(x) > 1)
  ties_y <- sum(table(y) > 1)
  out <- pspearman::spearman.test(x, y, alternative = "two.sided", approximation = "t-distribution") %>% 
    broom::tidy()
  return(data.frame(
    estimate = out$estimate, 
    statistic = out$statistic, 
    p.value = out$p.value,
    ties_x = ties_x,
    ties_y = ties_y
  ))
}

重新运行滑动计算后,筛选出rho相同的行:

Results %>% 
  group_by(estimate) %>% 
  filter(n() > 1) %>% 
  select(estimate, p.value, ties_x, ties_y)

你会发现,这些行的ties_x或ties_y必然存在差异,这就是p值不同的根源。

3. 关于ggplot的视觉误差

先排除数据本身的问题:如果上面的筛选结果显示p值数值确实不同,那和ggplot的颜色插值无关。如果数值相同但颜色显示有差异,你可以尝试将p值转为离散型变量(比如分箱),或者调整颜色标尺的精度来验证。

4. 两种解决方案

方案一:保留结校正(pspearman的优势)

如果你的数据确实存在较多秩结,推荐继续使用pspearman的结果——不同p值其实是更准确的统计结果,反映了不同窗口数据分布的差异。

方案二:使用经典无校正的t分布近似

如果你需要严格保证相同rho和n对应相同p值,可以自己实现经典的Spearman t检验公式:

classicSpearman <- function(x, y) {
  r <- cor(x, y, method = "spearman")
  n <- length(x)
  # 经典t统计量公式
  t_stat <- r * sqrt((n - 2)/(1 - r^2))
  # 双侧p值
  p_val <- 2 * pt(abs(t_stat), df = n - 2, lower.tail = FALSE)
  return(data.frame(
    estimate = r, 
    statistic = t_stat, 
    p.value = p_val
  ))
}

替换psSpearman为这个函数后,相同rho和n的窗口p值就会完全一致,但注意:这种方法在多结场景下p值的准确性会下降。

5. 额外验证:确保窗口样本量一致

虽然你设置了allow.fewer = FALSE,但还是可以在函数中加入样本量统计,确认所有窗口的n都是20:

psSpearman <- function(x, y) {
  n <- length(x)
  ties_x <- sum(table(x) > 1)
  ties_y <- sum(table(y) > 1)
  out <- pspearman::spearman.test(x, y, alternative = "two.sided", approximation = "t-distribution") %>% 
    broom::tidy()
  return(data.frame(
    estimate = out$estimate, 
    statistic = out$statistic, 
    p.value = out$p.value,
    n = n,
    ties_x = ties_x,
    ties_y = ties_y
  ))
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:25:59