Web-enabling R functions with CGI on a Mac OS X desktop

November 7, 2010

I write many R functions for my own use and for use in class. I have been making these functions available from a web page for some time, and finally decided to just post a simple example to make it easy for others to do the same. This is just an example based on the “Rcgi” package from David Firth, and for full details of using R with CGI, see http://www.omegahat.org/CGIwithR/. Download the document on using R with CGI. It’s titled “CGIwithR: Facilities for Processing Web Forms with R”.

Of course, if you don’t have R at all, then download R and install it from http://www.r-project.org/. Then use the R package manager to install the Rcgi package.

You need two program files to get everything working.
(a) The html file that is the web form for input data.
(b) The R file, with special tags for use with the CGIwithR package.

Our example will be simple, i.e., a calculator to work out the monthly payment on a standard fixed rate mortgage. The three inputs are the loan principal, annual loan rate, and the number of remaining months to maturity.

But first, let’s create the html file for the web page that will take these three input values. We call it “mortgage_calc.html”. The code is all standard, for those familiar with html, and even if you are not used to html, the code is self-explanatory.


<html>
<head>
<title>Monthly Mortgage Payment Calculator</title>
</head>

<FORM action="/cgi-bin/R.cgi/mortgage_calc.R" method="POST">
<body>
Loan Principal: <INPUT name="L" value="" size=5><p>
Annual Loan Rate: <INPUT name="rL" value="" size=5><p>
Remaining months: <INPUT name="N" value="" size=5><p>

<P><INPUT type="submit" size=3>

</body>
</html>

Notice that line 06 will be the one referencing the R program that does the calculation. The three inputs are accepted in lines 08–10. Line 12 sends the inputs to the R program.

Next, we look at the R program, suitably modified to include html tags. We name it “mortgage_calc.R”.

#! /usr/bin/R

tag(HTML)
	tag(HEAD)
		tag(TITLE)
			cat("Mortgage Monthly Payment Calculator")
		untag(TITLE)
	untag(HEAD)

tag(h3)
	cat("Mortgage Monthly Payment Calculator")
untag(h3)

lf(2)
tag(BODY)

tag(p)
	tag(b)
		cat("Inputs:")
	untag(b)
	
	tag(p)
	L = as.numeric(scanText(formData$L))
	cat("Loan Principal: ")
	cat(L)
	
	tag(p)
	rL = as.numeric(scanText(formData$rL))
	cat("Annual Loan Rate: ")
	cat(rL)
	
	tag(p)
	N = as.numeric(scanText(formData$N))
	cat("Remaining months: ")
	cat(N)
untag(p)

lf(2)
tag(p)
	cat("Monthly Loan Payment: ")
untag(p)

r = rL/12
mp = r*L/(1-(1+r)^(-N))
cat(mp)

untag(BODY)
untag(HTML)

We can see that all html calls in the R program are made using the “tag()” construct. Lines 22–35 take in the three inputs from the html form. Lines 43–44 do the calculations and line 45 prints the result. The “cat()” function prints its arguments to the web browser page.

Okay, we have seen how the two programs (html, R) are written and these templates may be used with changes as needed. We also need to pay attention to setting up the R environment to make sure that the function is served up by the system. The following steps are needed:

  1. Make sure that your Mac is allowing connections to its web server. Go to System Preferences and choose Sharing. In this window enable Web Sharing by ticking the box next to it.
  2. Place the html file “mortgage_calc.html” in the directory that serves up web pages. On a Mac, there is already a web directory for this called “Sites”. It’s a good idea to open a separate subdirectory called (say) “Rcgi” below this one for the R related programs and put the html file there.
  3. The R program “mortgage_calc.R” must go in the directory that has been assigned for CGI executables. On a Mac, the default for this directory is “/Library/WebServer/CGI-Executables” and is usually referenced by the alias “cgi-bin” (stands for cgi binaries). Drop the R program into this directory.
  4. Two more important files are created when you install the “Rcgi” package. The CGIwithR installation creates two files:
    (a) A hidden file called “.Rprofile”
    (b) A file called R.cgi

    Place both these files in the directory: /Library/WebServer/CGI-Executables

    If you cannot find the .Rprofile file then create it directly by opening a text editor and adding two lines to the file:

    #! /usr/bin/R
    library(CGIwithR,warn.conflicts=FALSE)

    Now, open the R.cgi file and make sure that the line pointing to the R executable in the file is showing

    R_DEFAULT=/usr/bin/R

    The file may actually have it as “#! /usr/local/bin/R” which is for Linux platforms, but the usual Mac install has the executable in “#! /usr/bin/R” so make sure this is done.

    Make both files executable as follows:

    chmod a+rx .Rprofile
    chmod a+rx R.cgi

  5. Finally, make the ~/Sites/Rcgi/ directory write accessible:

    chmod a+wx ~/Sites/Rcgi

Just being patient and following all the steps makes sure it all works well. Having done it once, it’s easy to repeat and create several functions. You can try this example out on my web server at the following link.

The inputs are as follows:

  • Loan principal (enter a dollar amount)
  • Annual loan rate (enter it in decimals, e.g., six percent is entered as 0.06)
  • Remaining maturity in months (enter 300 if the remaining maturity is 25 years)
Advertisements

Asynchronicity

November 6, 2010

The world is becoming ever more asynchronous. We do many things together, but this has become increasingly likely to be done at arms length. Face to face meetings have become less likely. Even worse, instead of talking on the phone, an email often suffices. Everything has become asynchronous. Truth be told, we probably like it this way!

There are examples everywhere. Instead of playing cards by sitting around a table, we now play internet poker. The same is true of chess, which is not only online but asynchronous, yours truly being a shining example of succumbing to this phenomenon. Instead of the phone, we send emails. Even TV watching, which used to be a joint family past time is now relegated to individual laptops in separate rooms. Instead of the entire nation watching a TV program at the same time, DVR technology has ensured that we all watch it on our own time. Even sports is watched with time delay in so many locations.

But making it convenient to consume entertainment has made it inconvenient for us to spend time together. We are all running to complete the ingestion of content, leaving little time for blank moments when we might spontaneously interact with each other. Is there no way out of this mess?

Here are some ways to fight this, for in this case the trend is not your friend.

  1. Consume less media. Most media consumption is now asynchronous and done independently of others. We do not watch the news together, not even sports. So just consume less of it. That goes directly to curtailing asynchronous consumption of media. Watch as much live as possible, with someone else. News and sports are ideally suited to this approach.
  2. Stop recording. It isn’t that hard. Just get rid of the DVR. This will also help in reducing the vast amounts of time spent on TV. It will also help you do just one thing at a time. I began taking my ipod along on a walk to listen to podcasts, and as a result stopped looking around and enjoying nature. I just missed out on the peaceful quiet on my night walks, and I did not realize how much I had enjoyed it till I stopped taking the ipod with me.
  3. Switch of all cell phones, computers, and singular distractions after some specific time each evening. This really works. My reading went up three-fold once I took this step. And my sleep was much better. There is plenty of evidence that imperceptibly flickering screens can mess up sleep for several hours. After switching off screens, I was not sleeping much more, but my sleep was of much better quality.
  4. Produce something every day in place of consumption. Instead of only reading, write something, and I do not mean emails. Responding to emails is not “producing” anything, and it does not bring deep satisfaction. But writing, even something trivial like a blog post, feels really good.
  5. Play team sports, and i don’t mean MPOG (multi player online games). Getting exercise this way is much better than the isolating act of going to the gym and pounding a treadmill alone. There is so much more stimulation getting exercise in groups. Even just hiking can be so much more than just an exercise in exercise. Do things with your hands where community is required, for example gardening clubs.
  6. Join a few meet up groups. Meetups are cool, new phenomena where interest groups organize get-togethers using web technology. The meetings are in person and synchronous.

Synchronicity is about community, and community is very important. However, we seem to be slipping into a world of asynchronicity. The good news is that this problem is beatable, one person at a time. As everyone, one by one, starts engaging in synchronous activity, we unwind asychronicity rapidly, because when people do things together, a network builds rapidly, and network effects rebuild synchronicity.