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)