# Post 6: Refactoring Part II: a generic proposal function

**Markov Chain Monte Carlo in Item Response Models**, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)

Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

In this post we refactor the proposal function from the previous post into a generic normal proposal function. This allows us to implement normal proposals for the (yet to be developed) samplers for the item parameters without duplicating code.

Our approach is to write a function which returns a function. We begin with a toy example to explain why that would work, implement a function that returns a normal proposal function, and then check that the refactored function works.

# The toy example

Writing functions that return functions sounds strange. Here we give a toy example to explain how it works.

Pretend that we want to write two similar functions for comparing numbers:

## A function to check if the parameter is less than three is.three.less.than

R is designed to allow us to make a function which can build other functions. For example, we can make an “is X less than” function that takes X as a variable and returns a function like the `is.three.less.than`

function above:

## We can write a function in R to build those other functions is.X.less.than

Now we can use `is.X.less.than`

to define our functions from before, which still work the same:

## Define them is.three.less.than

### For the curious: Why does that even work?

This works because functions in R are implemented as a kind of paired object called a closure. A closure contains both the “text” of the function to be run and an “environment” which can contain additional variables.

In the example above, the `is.X.less.than`

function returned a closure which contained both the “text” of `function( b.value ) { return( X < b.value )}`

and the value of `X`

. To see this for our example, we simply call the generated `is.three.less.than`

function without parenthesis:

is.three.less.than ## function( b.value ) { ## return( X < b.value ) ## } ## < environment: 0x3489ee8 >

And peek inside the environment with the `ls(...)`

function, to see that it does contain `X`

:

ls( envir=environment(is.three.less.than) ) ## [1] "X"

And even see what `X`

is set to in the environment of `is.three.less.than`

:

environment(is.three.less.than)$X ## [1] 3

Similarly, for the other function, we get

environment(is.two.less.than)$X ## [1] 2

as expected.

# A function to return a proposal function

Recall that in post 5 we defined the person ability proposal function to be:

## Proposal function for the person ability parameters prop.th.abl

If we were okay with duplicating the code, we could copy the text of `prop.th.abl`

and change all of the names from depending on `th`

to depending on the name of the other parameter (e.g. `a`

).

Instead, we shall write a function which takes the name of the parameter as a variable and returns the equivalent function. Here we interleave comments for what the person ability version would have been:

## Write a function to return a proposal function for that parameter generic.normal.proposal

Then implementing the refactored proposal function is simple:

prop.th.abl.refactor

# Testing the refactored code

Here we see if the sampler will produce the same output with the refactored code in place.

## Load the necessary code from this and previous posts source('http://mcmcinirt.stat.cmu.edu/setup/post-6.R') ## Check that we have the version from Post 4. head(prop.th.abl) ## 1 function (state) ## 2 { ## 3 th.old

That the output is identical suggests that the code was refactored correctly.

**leave a comment**for the author, please follow the link and comment on their blog:

**Markov Chain Monte Carlo in Item Response Models**.

R-bloggers.com offers

**daily e-mail updates**about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.

Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.