scale_y_log10()为何会影响ggscatter中的Kendall相关p值?
问题描述
使用ggpubr包的ggscatter绘制两个连续变量的相关图,指定Kendall秩系数并自动添加p值。因其中一个测量值分布范围大,尝试用scale_y_log10()对Y轴做对数转换,但发现转换后图中显示的Kendall相关系数和p值发生了变化。相关示例数据及代码如下:
示例数据
sampledata <- structure(list(ID = c(1, 2, 3, 4, 5), Measure1 = c(10, 10, 50, 0, 100), Measure2 = c(5, 3, 40, 30, 20), timepoint = c(1, 1,1, 1, 1), time = structure(c(18628, 19205, 19236, 19205, 19205), class = "Date"), event = c(1, 1, NA, NA, NA), eventdate = structure(c(18779,19024, NA, NA, NA), class = "Date")), row.names = c(NA, -5L), class = "data.frame")
未做对数转换的代码及结果
ggscatter(data = sampledata, x = "Measure2", y = "Measure1", add = "reg.line", conf.int = TRUE, cor.coef = TRUE, cor.method = "kendall", xlab = "measure2", ylab = "measure1", color="#0073C2FF" )
输出结果:Kendall相关系数τ=0.11,P=0.8。
加入对数转换的代码及结果
ggscatter(data = sampledata, x = "Measure2", y = "Measure1", add = "reg.line", conf.int = TRUE, cor.coef = TRUE, cor.method = "kendall", xlab = "measure2", ylab = "measure1", color="#0073C2FF" ) + scale_y_log10()
输出结果:Kendall相关系数τ=0.55,P=0.28。
原因解释
1. Kendall秩系数的计算核心是数据的秩次排序
Kendallτ系数是**基于变量的秩次(即数值在整体中的排序位置)**来衡量相关性的,和原始数值的绝对大小无关。当你对Measure1做log10转换时,会直接改变该变量的数值排序关系:
- 原始
Measure1的数值为[10,10,50,0,100],对应的秩次(从小到大)是[2.5,2.5,4,1,5](两个10并列,取平均秩次); - 转换后
log10(Measure1)的数值(忽略无法取对数的0)为[1,1,1.69897, NA, 2],对应的秩次变为[1.5,1.5,3, NA,4]。
秩次的变化直接导致Kendall系数和p值的改变。
2. scale_y_log10()是数据层面的转换而非仅坐标轴显示
很多人会误以为scale_y_log10()只是调整坐标轴的显示方式,但实际上,当你给ggscatter加上这个图层后,ggpubr会先对Y轴数据做对数转换,再基于转换后的数据计算Kendall系数和回归线,而不是先计算原始数据的统计量再转换坐标轴。
3. 手动验证可确认结论
你可以通过手动计算来验证这一点:
- 计算原始数据的Kendall系数:
cor.test(sampledata$Measure2, sampledata$Measure1, method = "kendall")
结果与未加对数转换的图一致(τ=0.1111, p=0.8)。
- 计算转换后数据的Kendall系数(处理0值为NA):
sampledata$log_Measure1 <- log10(sampledata$Measure1) cor.test(sampledata$Measure2, sampledata$log_Measure1, method = "kendall", na.action = "na.omit")
结果与加对数转换的图一致(τ=0.5556, p=0.2857)。
解决方案(若需保留原始数据的统计量)
如果你的需求是基于原始数据计算Kendall系数,但用对数转换优化坐标轴显示,可以先手动计算原始数据的相关系数,再将其添加到图中:
# 先计算原始数据的Kendall系数 cor_result <- cor.test(sampledata$Measure2, sampledata$Measure1, method = "kendall") tau_val <- round(cor_result$estimate, 2) p_val <- round(cor_result$p.value, 2) # 绘图并手动添加系数 ggscatter(data = sampledata, x = "Measure2", y = "Measure1", add = "reg.line", conf.int = TRUE, xlab = "measure2", ylab = "measure1", color="#0073C2FF" ) + scale_y_log10() + annotate("text", x = max(sampledata$Measure2)*0.7, y = max(sampledata$Measure1)*0.7, label = paste0("τ = ", tau_val, ", P = ", p_val))
内容的提问来源于stack exchange,提问作者Max
相关产品推荐
相关产品推荐

