Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
103 views
in Technique[技术] by (71.8m points)

r - How to apply succesively the same change to each argument of a function?

I am trying to figure out how to perform an elasticity analysis to a model I have developed. To do so, I intend to apply a 10% on each parameter of the model and measure the change in the output. I have written a simple function including all the parameter as arguments.

My challenge is that I don't know how to automatize this process to all the arguments with an apply function or a loop.

Let's take a dummy function as an example:

model <- function(a=1, b=1, c=1){
   result <- a+(10*b)+(100*c)
   return(result)
   }

I would like to apply the same change to each parameter (+10% of its value) and produce a run for each iteration. For example, if I had to do it manually it would like this:

output_a <- model(a=1.1)
> 111.1

output_b <- model(b=1.1)
> 111

output_c <- model(c=1.1)
> 121

Ideally, all of the outputs would be in the same dataframe to easily process them in the future. Any thoughts on this? Perhaps an existing post I couldn't find?

question from:https://stackoverflow.com/questions/65908167/how-to-apply-succesively-the-same-change-to-each-argument-of-a-function

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Create a grid of the desired values, subset it down to those needed and then Map or mapply over it or in (3) directly generate it.

v <- c(1, 1.1)

# either of these would be ok
g <- expand.grid(a = v, b = v,  c = v)
# g <- do.call("expand.grid", Map(function(x) v, c("a", "b", "c")))

g <- g[rowSums(g != 1) == 1, ]

# either of these would be ok
transform(g, result = mapply("model", g$a, g$b, g$c))
# transform(g, result = do.call("mapply", c("model", g)))

giving:

    a   b   c result
2 1.1 1.0 1.0  111.1
3 1.0 1.1 1.0  112.0
5 1.0 1.0 1.1  121.0

2) There are also a number of list comprehension packages (comprehenr, eList, listcompr) that can be used:

library(listcompr)
gen.data.frame(data.frame(a, b, c, result = model(a, b, c)), 
  a = v, b = v, c = v, (a != 1) + (b != 1) + (c != 1) == 1)

giving:

    a   b   c result
1 1.1 1.0 1.0  111.1
2 1.0 1.1 1.0  112.0
3 1.0 1.0 1.1  121.0

3) diag We can directly create the g matrix using diag:

g <- diag(.1, 3) + 1
colnames(g) <- c("a", "b", "c")
cbind(g, result = apply(g, 1, function(x) model(x[1], x[2], x[3])))

giving this matrix:

       a   b   c result
[1,] 1.1 1.0 1.0  111.1
[2,] 1.0 1.1 1.0  112.0
[3,] 1.0 1.0 1.1  121.0

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...