It is easy to build a Gaussian kernel function so that it can handle a vector input:
K_gaussian <- function(x){return(1/sqrt(2*pi)*(exp(-0.5*x*x)))}
K_gaussian(seq(-1,1,0.5))
# [1] 0.2419707 0.3520653 0.3989423 0.3520653 0.2419707
But I run into trouble when I try to code up, for example, an Epanechnikov kernel:
K_ep <- function(x){if(abs(x)>1){return(0)} else{return(3/4*(1-x*x))}}
because the if statement messed things up. For example, the following doesn't give vectored output:
K_ep(seq(-2,2,0.25))
# [1] 0
Warning message:
In if (abs(x) > 1) { :
the condition has length > 1 and only the first element will be used
How can I fix this problem?
You have two options to vectorize your function.
Since you only have one parameter, the easiest option here is to use sapply
K_ep(seq(-2,2,0.25))
sapply(seq(-2, 2, 0.25), K_ep)
## [1] 0.00000 0.00000 0.00000 0.00000 0.00000 0.32812 0.56250
## [8] 0.70312 0.75000 0.70312 0.56250 0.32812 0.00000 0.00000
## [15] 0.00000 0.00000 0.00000
However, sometimes you want to vectorize over many parameters and sapply cannot apply anymore. You will need mapply or Vectorize (a wrapper)
K_epvect <- Vectorize(K_ep, vectorize.args = "x")
K_epvect(seq(-2,2,0.25))
## [1] 0.00000 0.00000 0.00000 0.00000 0.00000 0.32812 0.56250
## [8] 0.70312 0.75000 0.70312 0.56250 0.32812 0.00000 0.00000
## [15] 0.00000 0.00000 0.00000
Use ifelse:
K_ep2 <- function(x){ifelse(abs(x)>1, 0, 3/4*(1-x*x))}
K_ep2(seq(-2,2,0.25))
[1] 0.000000 0.000000 0.000000 0.000000 0.000000 0.328125 0.562500 0.703125 0.750000 0.703125 0.562500 0.328125 0.000000 0.000000 0.000000
[16] 0.000000 0.000000
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With