Home > Enterprise >  Call objects based on one class with the different attributes
Call objects based on one class with the different attributes

Time:05-31

Is it possible to call objects with different attributes based on one class? For example here i want to have zlab attribute for one object and not for another one. I tried to use do.call with structure, but it doesn't work, as I thought. Or maybe it should be constructed in some other way?

chart <- function(domain, n, f, col, zlab, ...) {
      x <- y <- seq(min(domain), max(domain), length.out = n)
      fun <- function(x, y) {}
      body(fun) <- substitute(f)
        do.call(
        lapply, structure(list(x = x, y = y, f = fun, 
                               col=col, zlab = zlab, ...), ...),
                class = "myChart")
    }

# plot method
plot.myChart <- function(x, ...) {
  z = outer(x$x, x$y, x$f)
  persp(x$x, x$y, z, col = x$col, zlab = x$zlab, ...)
}

# object call
chr1 <- chart(c(-6, 6), 
             n = 30, 
             sqrt(x^2   y^2),
             col = 'blue',
             zlab = "Height")

chr2 <- chart(c(-5, 5), 
             n = 30, 
             x^2   y^2,
             col = 'green')
plot(chr1)
plot(chr2)

CodePudding user response:

You can simply add defaults for each argument, so that if any are skipped, they have a sensible fallback. This is a bit harder with f, but can be done inside the function using a combination of missing, match.call and quote:

chart <- function(domain = c(-1, 1), n = 10, f, col = 'gray90', zlab = '', ...) 
{
      x <- y <- seq(min(domain), max(domain), length.out = n)
      f <- if(missing(f)) quote(x   y) else match.call()$f
      
      structure(list(x = x, y = y, f = as.function(c(alist(x=, y=), f)), 
                     col = col, zlab = zlab, ...),
                class = "myChart")
}

# plot method
plot.myChart <- function(x, ...) {
  z = outer(x$x, x$y, x$f)
  persp(x$x, x$y, z, col = x$col, zlab = x$zlab, ...)
}

# object call
chr1 <- chart(c(-6, 6), 
             n = 30, 
             sqrt(x^2   y^2),
             col = 'blue',
             zlab = "Height")

chr2 <- chart(c(-5, 5), 
             n = 30, 
             x^2   y^2,
             col = 'green')

plot(chr1)

plot(chr2)

Note we even get a result with no arguments passed to chart at all.

chr3 <- chart()
plot(chr3)

Created on 2022-05-30 by the reprex package (v2.0.1)

CodePudding user response:

Maybe this helps

chart <- function(domain, n, f, col, zlab, ...) {
      x <- y <- seq(min(domain), max(domain), length.out = n)
      fun <- function(x, y) {}
      body(fun) <- substitute(f)
      structure(c(list(x = x, y = y, f = fun, col=col, zlab = zlab), 
          c(...)), class = "myChart")
       
    }

-testing

chr1 <- chart(c(-6, 6), 
             n = 30, 
             sqrt(x^2   y^2),
             col = 'blue',
             zlab = "Height")
             
chr2 <- chart(c(-5, 5), 
                          n = 30, 
                          x^2   y^2,
                          zlab = NULL,
                          col = 'green')
plot(chr1)
plot(chr2)
  •  Tags:  
  • r oop
  • Related