我已经创建了一个新的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( )
但是,当我在geom中使用aes时它没有运行:
df1 %>%
ggplot(.) +
geom_ray( aes( x = factor1, y = vector1 ) )
# Return:
Erreur : stat_ydensity requires the following missing aesthetics: x, y
有人可以帮我解决一下吗?
谢谢
问题是你使用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))
或者在函数调用中添加重要的参数名称,而不是仅使用...
(你可能想要放松空白区域,并且不需要在行尾使用;
。)
填满我的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 ) ;
} ;
谢谢您帮忙。