From the example here I tried to make the sum as class "stepfun". I thought, as.stepfun
is the right choice, but my ideas don't work. What is wrong?
y1 <- c(0, 1, 2, 0)
x1 <- c(1, 2, 3)
f1 <- stepfun(x = x1, y = y1)
print(class(f1))
# [1] "stepfun" "function" # OK!!!
plot(f1)
y2 <- c(0, 1, 0)
x2 <- c(1.5, 2.5)
f2 <- stepfun(x = x2, y = y2)
plot(f2)
fs <- function(x, f1, f2) {
# y <- f1(x) f2(x) # OK
# y <- as.stepfun(x = x, y = y, ties = "ordered", right = FALSE) # does not work
# return(y) # does not work
return(f1(x) f2(x))
}
print(class(fs)) # [1] "function"
# attributes(fs) # no new information...
fm <- function(x, f1, f2) {
return(f1(x) * f2(x))
}
print(class(fm)) # [1] "function"
Example as.
for data.frame
which works as expected:
z <- c(1, 2)
class(z) # [1] "numeric"
class(as.data.frame(z)) # [1] "data.frame"
About internals of stepfun
function (x, y, f = as.numeric(right), ties = "ordered", right = FALSE)
{
if (is.unsorted(x))
stop("stepfun: 'x' must be ordered increasingly")
n <- length(x)
if (n < 1)
stop("'x' must have length >= 1")
n1 <- n 1L
if (length(y) != n1)
stop("'y' must be one longer than 'x'")
rval <- approxfun(x, y[-if (right)
n1
else 1], method = "constant", yleft = y[1L], yright = y[n1],
f = f, ties = ties)
class(rval) <- c("stepfun", class(rval))
attr(rval, "call") <- sys.call()
rval
}
CodePudding user response:
The fs
function needs the "stepfun"
class, not the results it returns. But your fs
object won't work as a "stepfun"
object, because R makes assumptions about those: they need to keep copies of the data that produced them, among other things. You can see what f1
keeps by looking at ls(environment(f1))
. I don't know how those objects are used, but presumably they are needed.
Edited to add:
To turn fs
into a "stepfun"
object, you could try as.stepfun(fs)
. But this fails, with the error message
Error in as.stepfun.default(fs) :
no 'as.stepfun' method available for 'x'
The error message isn't the best (x
is the internal name of the first argument, and in my opinion it would make more sense to say there's no method available for fs
), but it's saying R doesn't know how to do the conversion you want.
CodePudding user response:
It looks like user2554330 is right about creating stepfun
objects directly from two other stepfun
objects, but here is a workaround in case it's useful:
x12 <- sort(unique(c(x1, x2)))
y12 <- f1(c(x12[1] - 1, x12)) f2(c(x12[1] - 1, x12))
f12 <- stepfun(x = x12, y = y12)