Reputation: 226
I have two vectors:
x <- c(-2.0,-1.75,-1.50,-1.25,-1.00,-0.75,-0.50,-0.25,0.00,0.25,0.50,0.75,1.00,1.25,1.50,1.75,2.00,2.25,2.50,2.75)
y <- c(37.0000,24.1602,15.06250,8.91016,5.00000,2.72266,1.56250,1.09766,1.00000,1.03516,1.06250,1.03516,1.00000,1.09766,1.56250,2.72266,5.00000,8.91016,15.06250,24.16016)
I am trying to create a function that given a number from vector x, it returns the corresponding y value(same index). For example, func(-2.0)
should return 37.0000
.
Currently I have this super ugly function that I don't think is what I am supposed to do:
func1 <- function(x) {
if (x==-2.0) {return (37.0000)}
else if (x==-1.75){return (24.1602)}
else if (x==-1.50){return (15.06250)}
else if (x==-1.25){return (8.91016)}
else if (x==-1.00){return (5.00000)}
else if (x==-0.75){return (2.72266)}
else if (x==-0.50){return (1.56250)}
else if (x==-0.25){return (1.09766)}
else if (x==0.00){return (1.00000)}
else if (x==0.25){return (1.03516)}
else if (x==0.50){return (1.06250)}
else if (x==0.75){return (1.03516)}
else if (x==1.00){return (1.00000)}
else if (x==1.25){return (1.09766)}
else if (x==1.50){return (1.56250)}
else if (x==1.75){return (2.72266)}
else if (x==2.00){return (5.00000)}
else if (x==2.25){return (8.91016)}
else if (x==2.50){return (15.06250)}
else if (x==2.75){return (24.16016)}
else {return (Inf)}
}
Upvotes: 1
Views: 50
Reputation: 179428
You seem to be doing an interpolation. The R function for interpolation is approx()
.
approx(x, y, xout = -2)
$x
[1] -2
$y
[1] 37
In practise it's easier to create an interpolation function using approxfun()
. Try this:
foo <- approxfun(x, y)
foo(-2)
[1] 37
You should probably avoid using an exact matching strategy using ==
or match()
. The reason is simple - if you use calculated values to find the index position, you could find that the match is inexact.
Compare:
y[ which(x == -2.0) ]
[1] 37
y[ which(x == -2.00000000001) ]
numeric(0)
Similarly:
y[match(-2.0, x)]
[1] 37
y[match(-2.0000000000001, x)]
[1] NA
Upvotes: 2
Reputation: 31171
For exact matching:
foo = function(u) {res=y[pmatch(u,x)];ifelse(is.na(res), Inf, res)}
#> foo(-2)
#[1] 37
#> foo(-1.8)
#[1] Inf
#> foo(-4)
#[1] Inf
Not sure about what you need but beware you can use linear interpolation (you can put method as constant instead of linear):
foo = approxfun(x,y, yleft=Inf, yright=Inf)
#> foo(-2)
#[1] 37
#> foo(-1.8)
#[1] 26.72816
#> foo(-4)
#[1] Inf
In this last case, the value is not Inf in the boundary domain defined by x
.
Upvotes: 2
Reputation: 47320
You don't really need a function for this, I suggest you just use:
y[x == -1.75]
x == -1.75 returns a boolean vector so it will pick the right value for y.
If you really want a function:
f <- function(x,y,xi){
return(y[x == xi])
}
Upvotes: 0
Reputation: 7153
Since x and y are the same length, put x as names of y
names(y)<-x
y
-2 -1.75 -1.5 -1.25 -1 -0.75 -0.5 -0.25 0 0.25 0.5 0.75 1 1.25 1.5 1.75 2
37.00000 24.16020 15.06250 8.91016 5.00000 2.72266 1.56250 1.09766 1.00000 1.03516 1.06250 1.03516 1.00000 1.09766 1.56250 2.72266 5.00000
2.25 2.5 2.75
8.91016 15.06250 24.16016
This way, you can call by the names, e.g.
y["-2"]
-2
37
y["-1.75"]
-1.75
24.1602
Upvotes: 0