Edit:下面描述的问题已在最近的版本中修复ggplot2
.
正如罗兰的评论中所建议的,您的问题是可重现的,并且似乎是由舍入错误引起的。在这一点上,这在我看来像是版本中引入的错误ggplot2_2.0.0
。我在下面推测其起源,但首先让我提出一个基于以下内容的解决方法boundary
选项。
PROBLEM:
df <- data.frame(var = seq(-100,100,10)/100)
as.list(df) # check the data
$var
[1] -1.0 -0.9 -0.8 -0.7 -0.6 -0.5 -0.4 -0.3 -0.2
[10] -0.1 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7
[19] 0.8 0.9 1.0
library("ggplot2")
p <- ggplot(data = df, aes(x = var)) +
geom_histogram(aes(y = ..count..),
binwidth = 0.1,
boundary = 0.1,
closed = "left")
p
SOLUTION
调整boundary
范围。在此示例中,设置略低于 1(例如 0.99)即可。您的用例也应该适合调整。
ggplot(data = df, aes(x = var)) +
geom_histogram(aes(y = ..count..),
binwidth = 0.05,
boundary = 0.99,
closed = "left")
(为了更好的视觉效果,我将 binwidth 缩小了)
另一种解决方法是引入您自己的模糊性,例如将数据乘以 1 加略小于机器零(参见eps
以下)。在ggplot2
模糊度乘以 1e-7(早期版本)或 1e-8(更高版本)。
CAUSE:
问题明显地出现在ncount
:
str(ggplot_build(p)$data[[1]])
## 'data.frame': 20 obs. of 17 variables:
## $ y : num 1 1 1 1 1 2 1 1 1 0 ...
## $ count : num 1 1 1 1 1 2 1 1 1 0 ...
## $ x : num -0.95 -0.85 -0.75 -0.65 -0.55 -0.45 -0.35 -0.25 -0.15 -0.05 ...
## $ xmin : num -1 -0.9 -0.8 -0.7 -0.6 -0.5 -0.4 -0.3 -0.2 -0.1 ...
## $ xmax : num -0.9 -0.8 -0.7 -0.6 -0.5 -0.4 -0.3 -0.2 -0.1 0 ...
## $ density : num 0.476 0.476 0.476 0.476 0.476 ...
## $ ncount : num 0.5 0.5 0.5 0.5 0.5 1 0.5 0.5 0.5 0 ...
## $ ndensity: num 1.05 1.05 1.05 1.05 1.05 2.1 1.05 1.05 1.05 0 ...
## $ PANEL : int 1 1 1 1 1 1 1 1 1 1 ...
## $ group : int -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 ...
## $ ymin : num 0 0 0 0 0 0 0 0 0 0 ...
## $ ymax : num 1 1 1 1 1 2 1 1 1 0 ...
## $ colour : logi NA NA NA NA NA NA ...
## $ fill : chr "grey35" "grey35" "grey35" "grey35" ...
## $ size : num 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 ...
## $ linetype: num 1 1 1 1 1 1 1 1 1 1 ...
## $ alpha : logi NA NA NA NA NA NA ...
ggplot_build(p)$data[[1]]$ncount
## [1] 0.5 0.5 0.5 0.5 0.5 1.0 0.5 0.5 0.5 0.0 1.0 0.5
## [13] 0.5 0.5 0.0 1.0 0.5 0.0 1.0 0.5
舍入误差?
好像:
df <- data.frame(var = as.integer(seq(-100,100,10)))
# eps <- 1.000000000000001 # on my system
eps <- 1+10*.Machine$double.eps
p <- ggplot(data = df, aes(x = eps*var/100)) +
geom_histogram(aes(y = ..count..),
binwidth = 0.05,
closed = "left")
p
(我已经删除了boundary
全部选项)
此行为在一段时间后出现ggplot2_1.0.1
。查看源代码,例如bin.R
and stat-bin.r
in https://github.com/hadley/ggplot2/blob/master/R
,并追踪计算count
导致功能bin_vector()
,其中包含以下几行:
bin_vector <- function(x, bins, weight = NULL, pad = FALSE) {
... STUFF HERE I HAVE DELETED FOR CLARITY ...
cut(x, bins$breaks, right = bins$right_closed,
include.lowest = TRUE)
... STUFF HERE I HAVE DELETED FOR CLARITY ...
}
通过将这些函数的当前版本与旧版本进行比较,您应该能够找到不同行为的原因...待续...
调试总结
By "patching"
the bin_vector
函数并将输出打印到屏幕上,看起来:
bins$fuzzy
正确存储模糊参数
非模糊bins$breaks
用于计算,但据我所知(如果我错了请纠正我)bins$fuzzy
不是。
如果我简单地替换bins$breaks
with bins$fuzzy
在顶端bin_vector
,返回正确的图。不是错误的证明,而是建议也许可以做更多的事情来模拟以前版本的行为ggplot2
.
在顶端bin_vector
我希望找到一个返回的条件bins$breaks
or bins$fuzzy
。我想现在已经不见了。
PATCHING
To "patch"
the bin_vector
函数,从 github 源复制函数定义,或者更方便地从终端复制函数定义:
ggplot2:::bin_vector
修改它(修补它)并将其分配到命名空间中:
library("ggplot2")
bin_vector <- function (x, bins, weight = NULL, pad = FALSE)
{
... STUFF HERE I HAVE DELETED FOR CLARITY ...
## MY PATCH: Replace bins$breaks with bins$fuzzy
bin_idx <- cut(x, bins$fuzzy, right = bins$right_closed,
include.lowest = TRUE)
... STUFF HERE I HAVE DELETED FOR CLARITY ...
ggplot2:::bin_out(bin_count, bin_x, bin_widths)
## THIS IS THE PATCHED FUNCTION
}
assignInNamespace("bin_vector", bin_vector, ns = "ggplot2")
df <- data.frame(var = seq(-100,100,10)/100)
ggplot(data = df, aes(x = var)) + geom_histogram(aes(y = ..count..), binwidth = 0.05, boundary = 1, closed = "left")
需要明确的是,为了清晰起见,对上面的代码进行了编辑:该函数有很多类型检查和其他计算,我已删除这些内容,但您需要修补该函数。在运行补丁之前,请重新启动 R 会话或detach
你当前加载的ggplot2
.
旧版本
意想不到的行为是NOT在版本中观察到2.0.9.3
or 2.1.0.1
并且似乎源自当前版本2.2.0.1
(或者也许更早2.2.0.0
,当我尝试调用它时,这给了我一个错误)。
要安装并加载旧版本,请说ggplot2_0.9.3
,创建一个单独的目录(覆盖当前版本没有意义),比如说ggplot2093
:
URL <- "http://cran.r-project.org/src/contrib/Archive/ggplot2/ggplot2_0.9.3.tar.gz"
install.packages(URL, repos = NULL, type = "source",
lib = "~/R/testing/ggplot2093")
要加载旧版本,请从本地目录调用它:
library("ggplot2", lib.loc = "~/R/testing/ggplot2093")