无法使用ggplot2覆盖多个stat_function

时间:2017-12-03 18:19:27

标签: r for-loop ggplot2

我有一个包含分箱变量VAR2_BY_NS_BIN和x-y数据对(MP_BINCORRECT_PROP)的表格。我想绘制数据点分箱,并使用stat_function为每个分箱绘制不同的行,每次使用for loop时使用不同的引用。

test_tab <- data.table(VAR2_BY_NS_BIN=c(0.0005478, 0.0005478, 0.002266, 0.002266, 0.006783, 0.006783, 0.020709, 0.020709, 0.142961, 0.142961),
                       MP_BIN=rep(c(0.505, 0.995), 5),
                       CORRECT_PROP=c(0.5082, 0.7496, 0.5024, 0.8627, 0.4878, 0.9368, 0.4979, 0.9826, 0.4811, 0.9989))

VAR2_BIN <- sort(unique(test_tab$VAR2_BY_NS_BIN)) #get unique bin values
LEN_VAR2_BIN <- length(VAR2_BIN) #get number of bins

col_base <- c("#FF0000", "#BB0033", "#880088", "#3300BB", "#0000FF") #mark bins with different colours

p <- ggplot(data = test_tab)

for (i in 1:LEN_VAR2_BIN) {
  p <- p + geom_point(data = test_tab[test_tab$VAR2_BY_NS_BIN==VAR2_BIN[i],],
                      aes(x = MP_BIN, y = CORRECT_PROP),
                      col = col_base[i],
                      alpha = 0.5) +
           stat_function(fun = function(t) {VAR2_BIN[i]*(t-0.5)+0.5}, col = col_base[i])
}

p <- p + xlab("MP") + ylab("Observed proportion")
print(p)

然而,上面的代码(一个可重现的例子)总是返回一个只绘制了最后stat_function行的图(在上面的例子中是第5行)。

以下代码(不使用for loop)有效,但实际上我有大量的垃圾箱,因此不太可行......

p <- p + stat_function(fun = function(t) {VAR2_BIN[1]*(t-0.5)+0.5}, col = col_base[1])
p <- p + stat_function(fun = function(t) {VAR2_BIN[2]*(t-0.5)+0.5}, col = col_base[2])
p <- p + stat_function(fun = function(t) {VAR2_BIN[3]*(t-0.5)+0.5}, col = col_base[3])
p <- p + stat_function(fun = function(t) {VAR2_BIN[4]*(t-0.5)+0.5}, col = col_base[4])
p <- p + stat_function(fun = function(t) {VAR2_BIN[5]*(t-0.5)+0.5}, col = col_base[5])

提前致谢!

1 个答案:

答案 0 :(得分:3)

您不需要for循环或stat_function。要绘制点,只需将MP_BINCORRECT_PROP映射到x和y,只需调用geom_point即可绘制点。对于线条,您可以动态创建必要的值(如下面的代码所示),并使用geom_line绘制那些。

library(tidyverse)

ggplot(test_tab %>% mutate(model=VAR2_BY_NS_BIN*(MP_BIN - 0.5) + 0.5), 
       aes(x=MP_BIN, colour=factor(VAR2_BY_NS_BIN))) +
  geom_point(aes(y=CORRECT_PROP)) +
  geom_line(aes(y=model)) +
  labs(colour="VAR2_BY_NS_BIN") +
  guides(colour=guide_legend(reverse=TRUE))

就你在for循环中遇到的问题而言,正在发生的是ggplot实际上并没有评估循环变量(i),直到你打印出情节。打印图时,i的值在循环结束时为5,因此这是您获得的唯一一行。您可以在Stack Overflow上找到与此问题相关的几个问题。 Here's one of them