I have 2 step function objects (ecdf objects to be exact). How to calculate a step function that is a difference or sum of these two?
-
2Welcome to StackOverflow! Can you please provide a [reproducible sample](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) of your data? – Punintended Jun 04 '18 at 16:48
-
1When asking for help, you should include a simple [reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) with sample input and desired output that can be used to test and verify possible solutions. – MrFlick Jun 04 '18 at 17:58
-
I disagree with the calls for a reproducible example -- this is a simple factual question. – user295691 Jun 04 '18 at 18:07
-
See also [here](https://stackoverflow.com/a/69744641/5784831) – Christoph Oct 29 '21 at 11:09
2 Answers
I just had the same question and found the follwoing nice solution
y1 <- c(0, 1, 2, 0)
x1 <- c(1, 2, 3)
f1 <- stepfun(x = x1, y = y1)
par(mfrow = c(2, 2))
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) {
return(f1(x) + f2(x))
}
fm <- function(x, f1, f2) {
return(f1(x) * f2(x))
}
x <- seq(0, 4, length.out = 100)
plot(x, fs(x, f1, f2), type = "s", main = "Sum f1+f2")
plot(x, fm(x, f1, f2), type = "s", main = "Multiplication f1*f2")
par(mfrow = c(1, 1))
There might be a more elegant version using +
and *
operators, see e.g. here...
foo <- structure(list(value = 1, txt = 'a'), class = 'foo')
`+.foo` <- function(leftfoo, rightfoo) { return (paste(leftfoo$txt, rightfoo$txt)) }
foo + foo
#[1] "a a"

- 6,841
- 4
- 37
- 89
Depends on what you need it for. An object of class stepfun
is in one sense a function; if a <- ecdf(rnorm(100))
, then a(0)
will evaluate to something close to .5
. So you can add them just by adding functions -- ecdf.sum <- function(x) { ecdf1(x) + ecdf2(x) }
. This will yield something that is effectively a step function, but not of class stepfun
or ecdf
.
Regardless, what you get out will not be an ecdf
object, because the values will not have the correct range. But to at least recover it as a step function, you can decompose it into knots:
knots.new <- sort(knots(ec1), knots(ec2))
ec.new <- stepfun(knots.new, c(0,ec1(knots.new) + ec2(knots.new)))
The c(0, ...
is because you need one more value than the knots (for the left-hand value of the step function), and for objects of type ecdf
0 is a safe value.

- 7,108
- 1
- 26
- 35