基于stat列表在复合geom中使用aes的问题

问题描述 投票:0回答:2

我已经创建了一个新的geom,其中包含平均值,2 sd误差条,1.5 IQR误差条,3e 25e,50e,75e和97e centile,以小提琴为基础进行观察。

# domestic functions
  #~~~~~~~~~~~~~~~~~~~
  IQR.interval.min <- function( vector )
  {
    quantile( vector, 0.25 ) - 1.5 * IQR( vector ) ;
  } ;

  IQR.interval.max <- function( vector )
  {
    quantile( vector, 0.75 ) + 1.5 * IQR( vector ) ;
  } ;

  SD.interval.min <- function( vector )
  {
    mean( vector ) - 2 * sd( vector ) ;
  } ;

  SD.interval.max <- function( vector )
  {
    mean( vector ) + 2 * sd( vector ) ;
  } ;
# My geom 
geom_ray <- function( ... , 


                   violin.param = list( draw_quantiles = c( 0.03, 0.25, 0.5, 0.75, 0.97 ), 
                                           scale = "count" ), 
                      point.param = list(),
                      IQR.param = list( colour = "black", width = 0.2 ),
                      mean.param = list(shape = 18, size = 4, colour = "darkgrey",
                                        position = position_nudge( x = 0.12 )),
                      SD.param = list( colour = "darkgrey",  width = 0.2,
                                       position = position_nudge( x = 0.12 ) ) 
                      )
{
  # graph
  #~~~~~~
  # Parameters
  param <- list( ... ) ;

  violin.param <- modifyList( param, violin.param ) ;

  point.param <- modifyList( param, point.param ) ;

  IQR.param <- modifyList( param, IQR.param ) ;

  mean.param <- modifyList( param, mean.param ) ;

  SD.param <- modifyList( param, SD.param ) ;

  # Stats
  violin.gg <- do.call( "stat_ydensity", 
                        modifyList( list( geom = GeomViolin, 
                                          position = "dodge" ), 
                                    violin.param ) ) ;
  point.gg <- do.call( "stat_identity", 
                       modifyList( list( geom = GeomPoint, 
                                         position = "identity" ), 
                                   point.param ) ) ;

  IQR.gg <-  do.call( "stat_summary", 
                      modifyList( list( fun.ymin = "IQR.interval.min",
                                        fun.ymax = "IQR.interval.max",
                                        geom = GeomErrorbar, 
                                        position = "identity" ), 
                                  IQR.param ) ) ;

  mean.gg <-  do.call( "stat_summary", 
                     modifyList( list( fun.y = "mean",
                                       geom = GeomPoint ), 
                                 mean.param ) ) ;

  SD.gg <-  do.call( "stat_summary", 
                     modifyList( list( fun.ymin = "SD.interval.min",
                                       fun.ymax = "SD.interval.max",
                                       geom = GeomErrorbar ), 
                                 SD.param ) ) ;

  # Output
  #~~~~~~~
  return( list( violin.gg,
                point.gg,
                IQR.gg,
                mean.gg,
                SD.gg 
                ) 
          )
} ;

当我在geom之外使用aes时,它运行良好。

# i.e.
vector1 <- rnorm(200, 10, 20) ;
factor1 <- factor( sample( c( "homme", "femme" ), 200, TRUE, c( 0.4,0.6 ) ) ) ;
data.frame( factor1 = factor1, vector1 = vector1 ) ->
  df1

require( dplyr ) ; require( ggplot2 ) ;

df1 %>%
  ggplot(.) + 
  aes( x = factor1, y = vector1 ) +
  geom_ray(  )

Raychart

但是,当我在geom中使用aes时它没有运行:

df1 %>%
  ggplot(.)  +
  geom_ray( aes( x = factor1, y = vector1 ) )
# Return:
Erreur : stat_ydensity requires the following missing aesthetics: x, y

有人可以帮我解决一下吗?

谢谢

r ggplot2
2个回答
0
投票

问题是你使用modifyList

在您失败的示例中,...中包含您的映射对象,但它只是没有参数名称的对象。 ...就像一个未命名的列表,例如:

test <- list(aes(x, y))

modifyList旨在按名称匹配列表。它抛出任何没有名字的东西:

test2 <- list(a = 1)
modifyList(test2, test)
$a
[1] 1

(请注意,test的映射已经消失。)`

这意味着您需要在使用函数时命名参数:

ggplot(df1) +
  geom_ray(mapping = aes(x = factor1, y = vector1))

或者在函数调用中添加重要的参数名称,而不是仅使用...

(你可能想要放松空白区域,并且不需要在行尾使用;。)


0
投票

填满我的geom,我偶然发现了一个关于aes和环境的新问题。

不考虑内部函数,在geom_text中,既不考虑aes参数aes(label = ifelse(is.outlier.all(data $ y),rownames(data),“”)。

这是一个reported issue但提出了修复(geom_(environment = environment(),...)或创建e

geom_mantaray <- function( mapping = NULL, 
                           data = NULL,
                           inherit.aes = TRUE,
                           outlier = TRUE,
                           ..., 
                           violin.param = list( draw_quantiles = c( 0.03, 0.25, 0.5, 0.75, 0.97 ), 
                                                scale = "count" ), 
                           point.param = list(),
                           IQR.param = list( colour = "black", width = 0.2 ),
                           mean.param = list(shape = 18, size = 4, colour = "darkgrey",
                                             position = position_nudge( x = 0.12 )),
                           SD1.param = list( colour = "darkgrey",  width = 0.1,
                                             position = position_nudge( x = 0.12 ) ),
                           SD2.param = list( colour = "darkgrey",  width = 0.1,
                                             position = position_nudge( x = 0.12 ) ),
                           SD3.param = list( colour = "darkgrey",  width = 0.1,
                                             position = position_nudge( x = 0.12 ) ),
                           text.param = list( size = 3,
                                              position = position_nudge( x = -0.06 ) )
)
{
  # Internal functions
  #~~~~~~~~~~~~~~~~~~~
  IQR.interval.min <- function( vector )
  {
    quantile( vector, 0.25 ) - 1.5 * IQR( vector ) ;
  } ;

  IQR.interval.max <- function( vector )
  {
    quantile( vector, 0.75 ) + 1.5 * IQR( vector ) ;
  } ;

  SD1.interval.min <- function( vector )
  {
    mean( vector ) - 1 * sd( vector ) ;
  } ;

  SD1.interval.max <- function( vector )
  {
    mean( vector ) + 1 * sd( vector ) ;
  } ;


  SD2.interval.min <- function( vector )
  {
    mean( vector ) - 2 * sd( vector ) ;
  } ;

  SD2.interval.max <- function( vector )
  {
    mean( vector ) + 2 * sd( vector ) ;
  } ;


  SD3.interval.min <- function( vector )
  {
    mean( vector ) - 3 * sd( vector ) ;
  } ;

  SD3.interval.max <- function( vector )
  {
    mean( vector ) + 3 * sd( vector ) ;
  } ;

  is.outlier.all <- function(vector) 
  {
    # SD outiliers
    ( vector - mean(vector) ) / sd(vector) ->
      Z.score ;

    abs(Z.score) > 3 * sd( vector) -> 
      is.outlierSD.log ;

    # MAD outiliers
    ( vector - median(vector) ) / mad(vector) ->
      Z.scoreMAD ;

    abs(Z.scoreMAD) > 3 * mad( vector) -> 
      is.outlierMAD.log ;

    # Tukey's fence outliers
    quantile( vector, probs = c(0.25, 0.75) ) -> quartile.num ;

    IQR(vector) -> iqr.num ;

    vector < ( quartile.num[1] - (1.5 * iqr.num) ) | 
      vector > ( quartile.num[2] + (1.5 * iqr.num) ) -> 
      is.outlierIQR.log ;

    # y values
    is.outlierIQR.log | is.outlierSD.log | is.outlierMAD.log -> is.outlier.log ;

    return( is.outlier.log ) ;
  } 

  e <- new.env()
  # graph
  #~~~~~~
  # Parameters
  param <- list( data = data,
                 mapping = mapping,
                 inherit.aes = inherit.aes,
                 environment = e,
                 ... ) ;

  violin.param <- modifyList( param, violin.param ) ;

  point.param <- modifyList( param, point.param ) ;

  IQR.param <- modifyList( param, IQR.param ) ;

  mean.param <- modifyList( param, mean.param ) ;

  SD1.param <- modifyList( param, SD1.param ) ;

  SD2.param <- modifyList( param, SD2.param ) ;

  SD3.param <- modifyList( param, SD3.param ) ;

  text.param <- modifyList( param, text.param ) ;

  # Stats
  violin.gg <- do.call( "stat_ydensity", 
                        modifyList( list( geom = GeomViolin, 
                                          position = "dodge" ), 
                                    violin.param ) ) ;
  point.gg <- do.call( "stat_identity", 
                       modifyList( list( geom = GeomPoint, 
                                         position = "identity" ), 
                                   point.param ) ) ;

  IQR.gg <-  do.call( "stat_summary", 
                      modifyList( list( fun.ymin = "IQR.interval.min",
                                        fun.ymax = "IQR.interval.max",
                                        geom = GeomErrorbar, 
                                        position = "identity" ), 
                                  IQR.param ) ) ;

  mean.gg <-  do.call( "stat_summary", 
                       modifyList( list( fun.y = "mean",
                                         geom = GeomPoint ), 
                                   mean.param ) ) ;

  SD1.gg <-  do.call( "stat_summary", 
                      modifyList( list( fun.ymin = "SD1.interval.min",
                                        fun.ymax = "SD1.interval.max",
                                        geom = GeomErrorbar ), 
                                  SD2.param ) ) ;

  SD2.gg <-  do.call( "stat_summary", 
                      modifyList( list( fun.ymin = "SD2.interval.min",
                                        fun.ymax = "SD2.interval.max",
                                        geom = GeomErrorbar ), 
                                  SD2.param ) ) ;

  SD3.gg <-  do.call( "stat_summary", 
                      modifyList( list( fun.ymin = "SD3.interval.min",
                                        fun.ymax = "SD3.interval.max",
                                        geom = GeomErrorbar ), 
                                  SD3.param ) ) ;

  text.gg <-  do.call( "stat_identity", 
                      modifyList( list(  aes(label = ifelse( is.outlier.all( data$y ), rownames( data ), "") ),
                                         geom = GeomText), 
                                  text.param ) ) ;

  list( violin.gg,
        point.gg,
        IQR.gg,
        mean.gg,
        SD1.gg,
        SD2.gg,
        SD3.gg ) ->
    output.gg ;

  if (outlier)
  {
    modifyList( output.gg, list( text.gg ) ) ->
      output.gg ;
  } 


  # Output
  #~~~~~~~
  return( output.gg ) ;
} ;

谢谢您帮忙。

© www.soinside.com 2019 - 2024. All rights reserved.