@@ -89,12 +89,9 @@ layer <- function(geom = NULL, stat = NULL,
8989 mapping <- validate_mapping(mapping )
9090 }
9191
92- if (is.character(geom ))
93- geom <- find_subclass(" Geom" , geom , parent.frame())
94- if (is.character(stat ))
95- stat <- find_subclass(" Stat" , stat , parent.frame())
96- if (is.character(position ))
97- position <- find_subclass(" Position" , position , parent.frame())
92+ geom <- check_subclass(geom , " Geom" , env = parent.frame())
93+ stat <- check_subclass(stat , " Stat" , env = parent.frame())
94+ position <- check_subclass(position , " Position" , env = parent.frame())
9895
9996 # Special case for na.rm parameter needed by all layers
10097 if (is.null(params $ na.rm )) {
@@ -344,15 +341,51 @@ Layer <- ggproto("Layer", NULL,
344341is.layer <- function (x ) inherits(x , " Layer" )
345342
346343
347- find_subclass <- function (super , class , env ) {
348- name <- paste0(super , camelize(class , first = TRUE ))
349- obj <- find_global(name , env = env )
350344
351- if (is.null(obj )) {
352- stop(" No " , tolower(super ), " called '" , class , " '." , call. = FALSE )
353- } else if (! inherits(obj , super )) {
354- stop(" Found object is not a " , tolower(super ), " ." , call. = FALSE )
345+ check_subclass <- function (x , subclass ,
346+ argname = tolower(subclass ),
347+ env = parent.frame()) {
348+ if (inherits(x , subclass )) {
349+ x
350+ } else if (is.character(x ) && length(x ) == 1 ) {
351+ name <- paste0(subclass , camelize(x , first = TRUE ))
352+ obj <- find_global(name , env = env )
353+
354+ if (is.null(obj ) || ! inherits(obj , subclass )) {
355+ stop(" Can't find `" , argname , " ` called \" " , x , " \" " , call. = FALSE )
356+ } else {
357+ obj
358+ }
359+ } else {
360+ stop(
361+ " `" , argname , " ` must be either a string or a " , subclass , " object, " ,
362+ " not " , obj_desc(x ),
363+ call. = FALSE
364+ )
355365 }
366+ }
356367
357- obj
368+ obj_desc <- function (x ) {
369+ if (isS4(x )) {
370+ paste0(" an S4 object with class " , class(x )[[1 ]])
371+ } else if (is.object(x )) {
372+ if (is.data.frame(x )) {
373+ " a data frame"
374+ } else if (is.factor(x )) {
375+ " a factor"
376+ } else {
377+ paste0(" an S3 object with class " , paste(class(x ), collapse = " /" ))
378+ }
379+ } else {
380+ switch (typeof(x ),
381+ " NULL" = " a NULL" ,
382+ character = " a character vector" ,
383+ integer = " an integer vector" ,
384+ logical = " a logical vector" ,
385+ double = " a numeric vector" ,
386+ list = " a list" ,
387+ closure = " a function" ,
388+ paste0(" a base object of type" , typeof(x ))
389+ )
390+ }
358391}
0 commit comments