R 分析动态生成的ggplot2代码时出错

R 分析动态生成的ggplot2代码时出错,r,ggplot2,R,Ggplot2,在下面的可复制示例中,我试图动态构建一个ggplot2函数调用,以便能够容纳未知数量的混合分布组件。代码生成此错误消息:解析错误(text=g)::8:0:输入意外结束。代码有什么问题?(我知道预计算绘图数据、将其存储在数据框中、将其熔化并提供给ggplot2的方法。我还想探讨以下选项。)谢谢 library(ggplot2) library(scales) library(RColorBrewer) library(mixtools) NUM_COMPONENTS <- 2 set.

在下面的可复制示例中,我试图动态构建一个
ggplot2
函数调用,以便能够容纳未知数量的混合分布组件。代码生成此错误消息:
解析错误(text=g)::8:0:输入意外结束
。代码有什么问题?(我知道预计算绘图数据、将其存储在数据框中、将其熔化并提供给
ggplot2
的方法。我还想探讨以下选项。)谢谢

library(ggplot2)
library(scales)
library(RColorBrewer)
library(mixtools)

NUM_COMPONENTS <- 2

set.seed(12345) # for reproducibility

data(diamonds, package='ggplot2')  # use built-in data
myData <- diamonds$price

calc.component <- function(x, lambda, mu, sigma) {
  lambda * dnorm(x, mean = mu, sd = sigma)
}


overlayHistDensity <- function(data, func) {

  # extract 'k' components from mixed distribution 'data'
  mix <- normalmixEM(data, k = NUM_COMPONENTS,
                     maxit = 100, epsilon = 0.01)
  summary(mix)

  DISTRIB_COLORS <- 
    suppressWarnings(brewer.pal(NUM_COMPONENTS, "Set1"))

  # plot histogram, empirical and fitted densities
  g <- "ggplot(data) +\n"

  for (i in seq(length(mix$lambda))) {
    args <- paste0("args.", i)
    assign(args, list(lambda = mix$lambda[i], mu = mix$mu[i],
                 sigma = mix$sigma[i]))
    g <- paste0(g,
                "stat_function(fun = func, args = ",
                args,
                ", aes(color = ",
                DISTRIB_COLORS[i], ")) +\n")
  }

  tailStr <- 
    "geom_line(aes(y = ..density..,colour = 'Empirical'),stat = 'density') +
     geom_histogram(aes(y = ..density..), alpha = 0.4) +
     scale_colour_manual(name = '', values = c('red', 'blue')) +
     theme(legend.position = 'top', legend.direction = 'horizontal')"

  g <- paste0(g, tailStr)
  gr <- eval(parse(text = g))
  return (gr)
}

overlayHistDensity(log10(myData), 'calc.component')
库(ggplot2)
图书馆(比例尺)
图书馆(RColorBrewer)
图书馆(混合工具)

NUM_COMPONENTS只要你意识到这是一个艰难的过程

如果在解析前查看
g
的值,则它是

ggplot(data) +
stat_function(fun = func, args = args.1, aes(color = #E41A1C)) +
stat_function(fun = func, args = args.2, aes(color = #377EB8)) +
geom_line(aes(y = ..density..,colour = 'Empirical'),stat = 'density') +
     geom_histogram(aes(y = ..density..), alpha = 0.4) +
     scale_colour_manual(name = '', values = c('red', 'blue')) +
     theme(legend.position = 'top', legend.direction = 'horizontal')
通常,
输入的意外结束
消息来自不平衡的引号或括号,但(显然)您没有遇到这个问题。问题在于颜色规格。文字十六进制颜色应指定为字符串

ggplot(data) +
stat_function(fun = func, args = args.1, aes(color = "#E41A1C")) +
stat_function(fun = func, args = args.2, aes(color = "#377EB8")) +
geom_line(aes(y = ..density..,colour = 'Empirical'),stat = 'density') +
     geom_histogram(aes(y = ..density..), alpha = 0.4) +
     scale_colour_manual(name = '', values = c('red', 'blue')) +
     theme(legend.position = 'top', legend.direction = 'horizontal')
没有引号,散列是一个注释字符,其余的行(特别是右括号)不包括在内,并且给出了您得到的错误。(请注意第一个代码段上的语法突出显示。)


也就是说,我认为您可以在不使用
eval(parse())
方法的情况下得到您想要的。特别是,看看
aes_string
,它允许通过字符串变量的值来指定使用哪个变量作为美学变量,并添加
stat
s或
geom
s列表(例如,可以是使用
lappy
创建的未预先指定的长度)。此外,您似乎指定了文字颜色,然后将它们映射为红色和蓝色;您可能想要
缩放\u颜色\u标识
?所有这些(最后一段)更多的是代码审查,而不是您实际询问的内容

只要你意识到这是一个艰难的过程

如果在解析前查看
g
的值,则它是

ggplot(data) +
stat_function(fun = func, args = args.1, aes(color = #E41A1C)) +
stat_function(fun = func, args = args.2, aes(color = #377EB8)) +
geom_line(aes(y = ..density..,colour = 'Empirical'),stat = 'density') +
     geom_histogram(aes(y = ..density..), alpha = 0.4) +
     scale_colour_manual(name = '', values = c('red', 'blue')) +
     theme(legend.position = 'top', legend.direction = 'horizontal')
通常,
输入的意外结束
消息来自不平衡的引号或括号,但(显然)您没有遇到这个问题。问题在于颜色规格。文字十六进制颜色应指定为字符串

ggplot(data) +
stat_function(fun = func, args = args.1, aes(color = "#E41A1C")) +
stat_function(fun = func, args = args.2, aes(color = "#377EB8")) +
geom_line(aes(y = ..density..,colour = 'Empirical'),stat = 'density') +
     geom_histogram(aes(y = ..density..), alpha = 0.4) +
     scale_colour_manual(name = '', values = c('red', 'blue')) +
     theme(legend.position = 'top', legend.direction = 'horizontal')
没有引号,散列是一个注释字符,其余的行(特别是右括号)不包括在内,并且给出了您得到的错误。(请注意第一个代码段上的语法突出显示。)


也就是说,我认为您可以在不使用
eval(parse())
方法的情况下得到您想要的。特别是,看看
aes_string
,它允许通过字符串变量的值来指定使用哪个变量作为美学变量,并添加
stat
s或
geom
s列表(例如,可以是使用
lappy
创建的未预先指定的长度)。此外,您似乎指定了文字颜色,然后将它们映射为红色和蓝色;您可能想要
缩放\u颜色\u标识
?所有这些(最后一段)更多的是代码审查,而不是您实际询问的内容

您遇到了几个问题:

  • ggplot
    的数据参数必须是data.frame,而不是向量
  • 必须引用以
    #
    开头的十六进制颜色名称,否则它们将被解释为注释
  • 您必须提供一个
    aes(x=)
    映射
  • 恒定的颜色定义不会出现在aes中
这应该起作用:

overlayHistDensity <- function(data, func) {
    # extract 'k' components from mixed distribution 'data'
    mix <- normalmixEM(data, k = NUM_COMPONENTS,
                       maxit = 100, epsilon = 0.01)
    summary(mix)

    DISTRIB_COLORS <- 
        suppressWarnings(brewer.pal(NUM_COMPONENTS, "Set1"))

    # plot histogram, empirical and fitted densities
    g <- "ggplot(as.data.frame(data), aes(x = data)) +\n"

    for (i in seq(length(mix$lambda))) {
        args <- paste0("args.", i)
        assign(args, list(lambda = mix$lambda[i], mu = mix$mu[i],
                          sigma = mix$sigma[i]))
        g <- paste0(g,
                    "stat_function(fun = func, args = ",
                    args,
                    ", color = '",
                    DISTRIB_COLORS[i], "') +\n")
    }

    tailStr <- 
        "geom_line(aes(y = ..density..,colour = 'Empirical'),stat = 'density') +
     geom_histogram(aes(y = ..density..), alpha = 0.4) +
     scale_colour_manual(name = '', values = c('red', 'blue')) +
     theme(legend.position = 'top', legend.direction = 'horizontal')"

    g <- paste0(g, tailStr)
    gr <- eval(parse(text = g))
    return (gr)
}

overlayHistDensity您遇到了几个问题:

  • ggplot
    的数据参数必须是data.frame,而不是向量
  • 必须引用以
    #
    开头的十六进制颜色名称,否则它们将被解释为注释
  • 您必须提供一个
    aes(x=)
    映射
  • 恒定的颜色定义不会出现在aes中
这应该起作用:

overlayHistDensity <- function(data, func) {
    # extract 'k' components from mixed distribution 'data'
    mix <- normalmixEM(data, k = NUM_COMPONENTS,
                       maxit = 100, epsilon = 0.01)
    summary(mix)

    DISTRIB_COLORS <- 
        suppressWarnings(brewer.pal(NUM_COMPONENTS, "Set1"))

    # plot histogram, empirical and fitted densities
    g <- "ggplot(as.data.frame(data), aes(x = data)) +\n"

    for (i in seq(length(mix$lambda))) {
        args <- paste0("args.", i)
        assign(args, list(lambda = mix$lambda[i], mu = mix$mu[i],
                          sigma = mix$sigma[i]))
        g <- paste0(g,
                    "stat_function(fun = func, args = ",
                    args,
                    ", color = '",
                    DISTRIB_COLORS[i], "') +\n")
    }

    tailStr <- 
        "geom_line(aes(y = ..density..,colour = 'Empirical'),stat = 'density') +
     geom_histogram(aes(y = ..density..), alpha = 0.4) +
     scale_colour_manual(name = '', values = c('red', 'blue')) +
     theme(legend.position = 'top', legend.direction = 'horizontal')"

    g <- paste0(g, tailStr)
    gr <- eval(parse(text = g))
    return (gr)
}

非常感谢您的回答!非常感谢您的回答!非常感谢您的回答!由于从
qplot()
转换到
ggplot()
,数据参数是意外遗留下来的。关于调试,在发布这个问题之前,我已经做了很多关于函数和非函数的调试。我不想冒犯任何人。所有的观点都很好;我只注意到与这个问题最直接相关的一个。我试图找到类似的问题,但在最后一个
g@AleksandrBlekh谢谢之后放了一个
return(g)
,我希望我没有冒犯(肯定不是故意的!),只是一个评论。一切都很好,不用担心!再次感谢您和@BrianDiggs!顺便说一句,我尝试这种方法而不是“标准”熔化方法的原因是对数刻度的问题:。我想知道,除了我的错误之外,它是否与这个
stat\u函数()
问题有关:。这个问题解决了吗?您对处理此类情况有何建议(通过
ggplot2
记录正常数据可视化)?我不知道
stat\u函数
问题。我倾向于完全避免使用
stat_函数
,并在绘图前进行此类处理,必要时使用第二个data.frame。我不知道这对你的情况有多好。非常感谢你的回答!由于从
qplot()
转换到
ggplot()
,数据参数是意外遗留下来的。关于调试,在发布这个问题之前,我已经做了很多关于函数和非函数的调试。我不想冒犯任何人。所有的观点都很好;我只注意到与这个问题最直接相关的一个。我试图找到类似的问题,但在最后一个
g@AleksandrBlekh谢谢之后放了一个
return(g)
,我希望我没有冒犯(肯定不是故意的!),只是一个同事