问题:
ggplot 手册明确指出 scale_y_log10()
和 coord_trans(y="log10")
表现不同。第一个转换数据,第二个转换坐标。因此,如果您必须在对数图中添加误差线,则不能使用前者,因为实际比例不是线性的,并且误差的计算必须在对数变换之前进行,而不是在对数变换之后进行。
但是,当将误差线(或其他范围)添加到以对数刻度绘制的某些数据时,存在某些范围将达到零并且绘图失败的风险。在这种情况下,绘制的变量不可能低于 0,因此可以将这些值安全地切割为任意低的数字,这样绘图就不会失败。
例子:
获取示例数据框:
url <- "https://copy.com/cfNBrcTLEfjiYXXa/d_dataframe.Rdata?download=1"
download.file(url, "d_dataframe.Rdata", method="curl")
load("d_dataframe.Rdata")
library(ggplot2)
p <- ggplot(d, aes(x=x, y=PDF))
查看对数刻度中的数据:p + geom_point(aes(colour=model)) + scale_y_log10()
p + geom_point(aes(colour=model)) + coord_trans(y="log10")
一切正常,数据看起来与 coord_trans() 和 scale_y_log10() 相同。但是,如果我添加一个摘要方法:p + stat_summary(fun.data = "mean_se", mult = 2) + scale_y_log10()
以上并不能正确代表实际的标准误差,但是:p + stat_summary(fun.data = "mean_se", mult = 2) + coord_trans(y="log10")
无法绘制,因为其中一个摘要(在这种情况下我使用标准误差)达到 0(或更少)并且对数刻度失败,通常情况下:Error in if (zero_range(range)) { : missing value where TRUE/FALSE needed
设置 y 限制不起作用,因为一些点范围被简单地删除:p + stat_summary(fun.data = "mean_se", mult = 2) + coord_trans(y="log10", limy=c(1e-10, 1.1))
我不希望这些线被删除,而只是为了到达图表的底部,以表明它们低于 0。我知道我可以手动计算错误,将它们过滤为 >0,然后用
geom_linerange()
绘制它们。或类似。但使用能力stat_summary()
非常方便快捷,并允许快速更改绘制的统计数据。同样的考虑也适用于 geom_smooth()
.有什么办法可以保留使用
stat_summary()
/geom_smooth()
仍然以对数刻度绘制数据?编辑:
一个示例解决方案是这样的(对于 2sd 点差):
maxf <- function(dati) {mean(dati) + 2*sd(dati)}
minf <- function(dati) {max(10e-8, mean(dati) - 2*sd(dati))}
然后使用:stat_summary(fun.y = mean, fun.ymin=minf, fun.ymax=maxf) + coord_trans(y="log10")
但是,每次我改变对汇总误差的看法时都必须对此进行调整(例如,如果我选择标准误差而不是标准差),并且不可能(?)对 geom_smooth()
使用这种方法.
最佳答案
一个简单且合理可行的解决方案是定义 maxf
和 minf
作为将函数作为参数的嵌套函数定义。
# Defining minf and maxf to take functions as input
minf <- function(f){function(dati) {max(1e-8, mean(dati) - f(dati))}}
maxf <- function(f){function(dati) {mean(dati) + f(dati)}}
# A plot that works
p + stat_summary(fun.y = mean, fun.ymin=minf(sd), fun.ymax=maxf(sd))
+ coord_trans(y="log10")
# If you change your mind and want something besides sd
se <- function(x){sd(x)/sqrt(length(x))}
p + stat_summary(fun.y = mean, fun.ymin=minf(se), fun.ymax=maxf(se))
+ coord_trans(y="log10")
这种方法有一些限制:你仍然需要重新定义
minf
和 maxf
如果你想要的误差线不是某种形式的均值加/减,你必须定义你的 f
功能是能够采用单个向量输入来给出向量输出。但我认为这比总是重新定义要好一点 minf
和 maxf
一直以来,为了一切。
关于r - 使用 stat_summary : summary range reaches zero 以对数刻度绘制数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30892670/