lunedì 5 dicembre 2011

The Art of R Programming - my two cents

What makes this book different from other books about R is stated clearly by the author Norman Matloff in the introduction:
"This book is not a compendium of the myriad types of statistical methods that are available in the wonderful R package. It really is about programming and cover programming-related topics missing from most other books on R".
Most books about R present a gentle introduction to the language and then jump to practical applications. Norman Matloff, across the 350 pages of this book, accompanies the reader in developing the necessary skills useful to write software in a proper way focusing on the characteristics and idiosyncrasies of the R language.

In each of the first six chapters of the book the author covers a different R data type: vector, matrix, list, data.frame and factor.   Starting from basic examples and progressing to more complex ones each data type is properly introduced and used in the proper context. Furthermore,  some extended examples are ameliorated or re-implemented along new type are introduced in order to show the expressivity of the language. The explanation of small details such as the use of the drop=FALSE argument in matrix/data.frame subsetting or the stringsAsFactor=FALSE argument when building up a data.frame are the proverbial icing on the cake which can make your day-by-day workflow more productive.
Chapter 7, 8 and 9 are the heart of the Art of R Programming introducing the structures, idioms, peculiarities and idiosyncrasies of R as programming language.
Chapter 7 presents how the typical programming structures are implemented in R and how to use them correctly: control statements, functions, recursion etc. are explained by clear and appropriate examples of increased complexity and usefulness.
Chapter 8 about doing math and simulation in R is a more 'traditional' chapter depicting the mathematical/statistical facilities embedded in R. Since the main selling-point of R is its statistical capabilities an introduction to their characteristics and use makes perfectly sense.
Chapter 9 covers S3 and S4 the two most commonly used paradigms of object-oriented programming (OOR) implemented in R. If you are going to start designing and developing R software in a proper and reusable form this chapter will provide all the necessary information and a good collection of examples tailored to R mathematical/statistical peculiarities.
Chapter 10 is about I/O and provides all the necessary directions needed to parse data in R locally and from the internet.
Chapter 11 is about string manipulation and it is less technical than former chapters, presenting a sort of cheat-sheet collection of the most common functions to handle string in R. The author covers the  string capabilities embedded in base R but advices to take a look at Hadley Wickham's stringr package for a more consistent handling of strings in R.
Chapter 12 introduces graphics in R providing a gentle overview of the huge R graphics capabilities but it doesn't present an in-depth discussion. Fortunately there are a lot of other books (for example Paul Murrel's R Graphics) dedicated to this subject which is indeed one of the R's strong points.
Chapter 13 about debugging is short but points out almost everything is important to know about debugging R code; furthermore it provides a wide vision about debugging in general: the author Norman Matloff is also the co-author of The Art of Debugging with GDB and DDD and clearly he knows the matter of which he speaks.
Chapter 14 covers strategies to handle the time/space trade-off in order to enhance the performance of R programs. In particular it explains the proper use of vectorization in order to speed up your code.
Chapter 15 and 16 are a sort of follow-up to chapter 14, meaning that they explain how to enhance the performance of your code by integrating R with other language, such as Python and C/C++ (Chapter 15) and by parallelizing your code. Both chapters provide an introductory glance on these topics but present sufficient coverage in order to be useful.
Conclusions:
Is it worth to buy this book? The short answer is YES. If you are serious in learning R in order to both analyze in the most appropriate and effective way your data (e.g. using the appropriate data type according your specific task) and to develop software, The Art of R programming will be beneficial to you.
Caveats: since the peculiar approach and aim of this book my advice is to buy this book together with a more statistical oriented, for example Rob Kabacoff's R in Action and one or two about graphics in R (e.g. Hrishi Mittal's R Graph Cookbook or Hadley Wickham's ggplot2 book).

Disclaimer: No Starch Press provided me a free copy for review.

mercoledì 16 novembre 2011

Weather forecast and good development practices

Inspired by this tutorial, I thought that it would be nice to have the possibility to have access to weather forecast directly from the R command line, for example for a personalized start-up message such as the one below:
Weather summary for Trieste, Friuli-Venezia Giulia:
The weather in Trieste is clear. The temperature is currently 14°C (57°F). Humidity: 63%.
Fortunately, thanks to the always useful Duncan Temple Lang's XML package (see here for a tutorial about XML programming under R), it is straightforward to write few lines of R code to invoke the google weather api for the location of interest, retrieve the XML file, parse it using the XPath paradigm and get the required informations:

address="Trieste"
url = paste( "http://www.google.com/ig/api?weather=", URLencode(address), sep="" )
xml = xmlTreeParse(url, useInternalNodes=TRUE) # take a look at the xml output:
# Get the required informations:
condition=xpathSApply(xml,"//xml_api_reply/weather/current_conditions/condition",xmlGetAttr,"data")
temp_c=xpathSApply(xml,"//xml_api_reply/weather/current_conditions/temp_c",xmlGetAttr,"data")
humidity=xpathSApply(xml,"//xml_api_reply/weather/current_conditions/humidity",xmlGetAttr,"data")
cat( paste("The Weather in ", address, " is ", condition, ". The temperature is ", temp_c, "°C. Humidity is ", humidity, "%.") )

Times ago I came to the conclusion that the best way to organize my R code is to create packages even for basic tasks. I know that It seems too much effort for this trivial task (and it was in the past) but fortunately, thanks to the Hadley Wickham's devtools package development It has become a piece of cake process (sort of)!

Below I present the minimal workflow I used to create this simple package. For a proper introduction to package development using devtools take a look at this link.

First create the skeleton for the project using the package.skeleton() function:
package.skeleton("pkg")
Read './pkg/Read-and-delete-me' file, compile the DESCRIPTION fiels according to your needs and delete './pkg/Read-and-delete-me'.
Now the devtools magic:
library("devtools")
pkg <- as.package("pkg") # pkg is the directory containing the structure created using package.skeleton()
Create your functions and documentation following the roxygen literate programming paradigm: basically you write your functions together with its documentation using in the preamble tags such as @param, @example, etc. to indicate the different constituents of the functions and devtools automagically will create the functions' documentation (.Rd files).
Then you test your code, try your examples, verify that your package passes the check without errors and warnings, build it and, if you like, you can ftp it directly to CRAN (disclaimer: I didn't check this feature)!
load_all(pkg, reset=T) # to reload the package without having to restart R
document(pkg) # to be used together with roxygen2 to creating the corresponding Rd files
run_examples(pkg) # to check the examples for the different functions
devtools:::check(pkg) # to verified if your package raises errors or warnings
devtools:::build(pkg)
install(pkg) # install your package
# release()

Final consideration: the devtools package improved significantly my day-by-day workflow and I want to thank Hadley Wickham for this and all the other valuable packages he gifted the R community! 
P.S. If you like to install the RWeather package I created using devtools, you can do it by typing:
install.packages("RWeather", repos="http://R-Forge.R-project.org")
or download the source code from here.
P.S.2 I'd like to thank Kay Cichini for this post which explains how to set-up the syntax-highlighting for the R code on Blogger.

Update: Thanks to the useful info I got from this Python module, now RWeather can show weather information from Yahoo! Weather, Google Weather and NOAA APIs.
From now the stable version of the package can be installed directly from CRAN:
install.packages("RWeather")

lunedì 31 ottobre 2011

R 2.14.0 is released!

The new R 2.14.0 is out! Get the source code from here.
Take a look at these posts for some miscellaneous advices to make the upgrade easier.
Also this thread on stackoverflow and this post contributed by Tal Galili can be of some value to make the procedure less painful.
Feel free to contribute with suggestions about how to upgrade your R installation.

mercoledì 27 luglio 2011

Word Cloud in R

A word cloud (or tag cloud) can be an handy tool when you need to highlight the most commonly cited words in a text using a quick visualization. Of course, you can use one of the several on-line services, such as wordle or tagxedo , very feature rich and with a nice GUI. Being an R enthusiast, I always wanted to produce this kind of images within R and now, thanks to the recently released Ian Fellows' wordcloud package, finally I can!
In order to test the package I retrieved the titles of the XKCD web comics included in my RXKCD package and produced a word cloud based on the titles' word frequencies calculated using the powerful tm package for text mining (I know, it is like killing a fly with a bazooka!).

library(RXKCD)
library(tm)
library(wordcloud)
library(RColorBrewer)
path <- system.file("xkcd", package = "RXKCD")
datafiles <- list.files(path)
xkcd.df <- read.csv(file.path(path, datafiles))
xkcd.corpus <- Corpus(DataframeSource(data.frame(xkcd.df[, 3])))
xkcd.corpus <- tm_map(xkcd.corpus, removePunctuation)
xkcd.corpus <- tm_map(xkcd.corpus, content_transformer(tolower))
xkcd.corpus <- tm_map(xkcd.corpus, function(x) removeWords(x, stopwords("english")))
tdm <- TermDocumentMatrix(xkcd.corpus)
m <- as.matrix(tdm)
v <- sort(rowSums(m),decreasing=TRUE)
d <- data.frame(word = names(v),freq=v)
pal <- brewer.pal(9, "BuGn")
pal <- pal[-(1:2)]
png("wordcloud.png", width=1280,height=800)
wordcloud(d$word,d$freq, scale=c(8,.3),min.freq=2,max.words=100, random.order=T, rot.per=.15, colors=pal, vfont=c("sans serif","plain"))
dev.off()

As a second example,  inspired by this post from the eKonometrics blog, I created a word cloud from the description of  3177 available R packages listed at http://cran.r-project.org/web/packages.
require(XML)
require(tm)
require(wordcloud)
require(RColorBrewer)
u = "http://cran.r-project.org/web/packages/available_packages_by_date.html"
t = readHTMLTable(u)[[1]]
ap.corpus <- Corpus(DataframeSource(data.frame(as.character(t[,3]))))
ap.corpus <- tm_map(ap.corpus, removePunctuation)
ap.corpus <- tm_map(ap.corpus, content_transformer(tolower))
ap.corpus <- tm_map(ap.corpus, function(x) removeWords(x, stopwords("english")))
ap.corpus <- Corpus(VectorSource(ap.corpus))
ap.tdm <- TermDocumentMatrix(ap.corpus)
ap.m <- as.matrix(ap.tdm)
ap.v <- sort(rowSums(ap.m),decreasing=TRUE)
ap.d <- data.frame(word = names(ap.v),freq=ap.v)
table(ap.d$freq)
pal2 <- brewer.pal(8,"Dark2")
png("wordcloud_packages.png", width=1280,height=800)
wordcloud(ap.d$word,ap.d$freq, scale=c(8,.2),min.freq=3,
max.words=Inf, random.order=FALSE, rot.per=.15, colors=pal2)
dev.off()

As a third example, thanks to Jim's comment, I take advantage of Duncan Temple Lang's RNYTimes package to access user-generate content on the NY Times and produce a wordcloud of 'today' comments on articles.
Caveat: in order to use the RNYTimes package you need a API key from The New York Times which you can get by registering to the The New York Times Developer Network (free of charge) from here.
require(XML)
require(tm)
require(wordcloud)
require(RColorBrewer)
install.packages(packageName, repos = "http://www.omegahat.org/R", type = "source")
require(RNYTimes)
my.key <- "your API key here"
what= paste("by-date", format(Sys.time(), "%Y-%m-%d"),sep="/")
# what="recent"
recent.news <- community(what=what, key=my.key)
pagetree <- htmlTreeParse(recent.news, error=function(...){}, useInternalNodes = TRUE)
x <- xpathSApply(pagetree, "//*/body", xmlValue)
# do some clean up with regular expressions
x <- unlist(strsplit(x, "\n"))
x <- gsub("\t","",x)
x <- sub("^[[:space:]]*(.*?)[[:space:]]*$", "\\1", x, perl=TRUE)
x <- x[!(x %in% c("", "|"))]
ap.corpus <- Corpus(DataframeSource(data.frame(as.character(x))))
ap.corpus <- tm_map(ap.corpus, removePunctuation)
ap.corpus <- tm_map(ap.corpus, content_transformer(tolower))
ap.corpus <- tm_map(ap.corpus, function(x) removeWords(x, stopwords("english")))
ap.tdm <- TermDocumentMatrix(ap.corpus)
ap.m <- as.matrix(ap.tdm)
ap.v <- sort(rowSums(ap.m),decreasing=TRUE)
ap.d <- data.frame(word = names(ap.v),freq=ap.v)
table(ap.d$freq)
pal2 <- brewer.pal(8,"Dark2")
png("wordcloud_NewYorkTimes_Community.png", width=1280,height=800)
wordcloud(ap.d$word,ap.d$freq, scale=c(8,.2),min.freq=2,
max.words=Inf, random.order=FALSE, rot.per=.15, colors=pal2)
dev.off()


giovedì 14 luglio 2011

R meets XKCD

Being a big fan of XKCD and, of course, of the R programming language, I thought that a package which allows to display my favorite strips  would something (useless) but cool!
So, mimicking the approach (and the code) of the fortunes package (thanks Achim Zeileis!), I created a simple package (names RXKCD) which allows the user to displays his favorite XKCD strip by selecting the specific number, randomly or simply displaying the current strip.
You can install the package using:
if (!require('RJSONIO')) install.packages('RJSONIO', repos = 'http://cran.r-project.org')
if (!require('png')) install.packages('png', repos = 'http://cran.r-project.org')
if (!require('ReadImages')) install.packages('ReadImages', repos = 'http://cran.r-project.org')
install.packages("RXKCD", repos="http://R-Forge.R-project.org")
And you can use it by typing:
library(RXKCD)
searchXKCD("someone is wrong")
getXKCD(386)
Below the result (xkcd license):


Update: The updated version of the package , which is available from CRAN (just type install.packages("RXKCD") ), allows the user to save the xkcd metadata database in a local directory (.Rconfig) and update it in order to have access to the latest XKCD info: see ?saveConfig and ?updateConfig.

venerdì 24 giugno 2011

Installing Multiple Version of R in parallel on the same machine - Mac OS X

In a few days I'm going to attend a Bioconductor Course; I was requested to install on my MacBook (Mac OS X 10.5.8) a developer version of R (plus ad hoc Bioconductor packages). In order to keep my old R installation ((2.13) along side the new one (2.14) I decided to use the RSwitch app (you can download from here) and the instructions you can read here.
In practical term, you type the following commands in Terminal:

sudo pkgutil --forget org.r-project.R.Leopard.fw.pkg
sudo pkgutil --forget org.r-project.R.Leopard.GUI.pkg
sudo pkgutil --forget org.r-project.R.Leopard.GUI64.pkg


You install the alternative version of R (for example, following the procedure depicted here) and then you can switch between the different version using the RSwitch GUI (see the below screenshot). So easy!



giovedì 14 aprile 2011

R 2.13.0 is released!

The new R 2.13.0 is out! Get the source code from here.
Take a look at these posts for some miscellaneous advices to make the upgrade easier.
Also this thread on stackoverflow and this post contributed by Tal Galili can be of some value to make the procedure less painful.
Feel free to contribute with suggestions about how to upgrade your R installation.

mercoledì 2 febbraio 2011