# Displaying multiple conditional distributions using lattice

I have a data frame which contains several true/false columns, some numeric and a class (target) variable which has true/false values.

Now, how can I produce with R multiple barplots for all numerical and factor columns without having to specify each data frame's column name and imposing the class attribute's distribution per each feature of the data frame?

Some example code :

mydata<-data.frame(age=c(15,10,20),sugar=c("3","2","5"),spinach=c("true","true","false"),meat=c("false","false","true"),milk=c("false","true","false"),class=c("true","false","false"))

age  sugar  spinach meat   milk   class
1  15     3    true   false   false   true
2  10     2    true   false   true   false
3  20     5   false   true    false  false


So how can i see the distribution of the class attribute imposed on all other columns of the dataframe (numerical or factors) ?

Here is an example from WEKA:

• As can be seen, you only have one numerical variable (age, because sugar will actually be treated as a factor): How would like to summarize it with other factors (quartiles, median, mean)?
– chl
Commented Nov 14, 2011 at 10:20
• There are many more rows on the actual data, this is just an example so sugar is not treated as factor (it takes values from 0-10). I would like to see the proportion of the class attribute that exists for each remaining attributes. In the case of numerical attributes (such as sugar and age) i would expect that some sort of binning is taking place. Commented Nov 14, 2011 at 12:58

Here is a (not so elegant) solution using lattice, where I consider quartiles in case the variables have numeric or integer values. Note that I assume that your classification factor is always in the latest position in your dataframe.

mydata <- data.frame(age=rnorm(100, 25, 4),
sugar=sample(0:10, 100, rep=T),
spinach=sample(c("true","false"), 100, rep=T),
meat=sample(c("true","false"), 100, rep=T),
milk=sample(c("true","false"), 100, rep=T),
class=sample(c("true","false"), 100, rep=T))

library(lattice)
library(gridExtra)
library(Hmisc)

plt <- list()
for (i in 1:(ncol(mydata)-1)) {
if (is.numeric(mydata[,i])) vv <- cut2(mydata[,i], g=4)
else vv <- mydata[,i]
plt[[i]] <- barchart(xtabs(~ vv + mydata[,"class"]), horizontal=F,
main=colnames(mydata)[i],
col=c("red","blue"), xlab="", ylab="", box.width=1,
scales=list(x=list(rot=ifelse(is.numeric(mydata[,i]),45,0))))
}
plt[[i+1]] <- barchart(xtabs(~ class, mydata), col=c("red","blue"),
xlab="", ylab="", box.width=1,
horizontal=F, main="class")

do.call(grid.arrange, plt)


Using the same dataset with 10 more variables

mydata <- data.frame(age=rnorm(100, 25, 4),
sugar=sample(0:10, 100, rep=T),
spinach=sample(c("true","false"), 100, rep=T),
meat=sample(c("true","false"), 100, rep=T),
milk=sample(c("true","false"), 100, rep=T),
replicate(10, sample(c("true","false"), 100, rep=T)),
class=sample(c("true","false"), 100, rep=T))


this is the base version (you will still need the Hmisc library):

opar <- par(mfrow=c(4,4))
for (i in 1:15) {
if (is.numeric(mydata[,i])) vv <- cut2(mydata[,i], g=4)
else vv <- mydata[,i]
barplot(xtabs(~ mydata[,"class"] + vv), col=c("red","blue"),
main=colnames(mydata)[i],
las=ifelse(is.numeric(mydata[,i]), 2, 1))
}
barplot(xtabs(~ class, mydata), col=c("red","blue"), main="class",
las=ifelse(is.numeric(mydata[,i]), 2, 1))
par(opar)

• A shorter version would be marginal.plot(mydata[,-ncol(mydata)], mydata, groups=class), with the latticeExtra package, although it doesn't match Weka diagrams.
– chl
Commented Nov 14, 2011 at 14:46
• Thank you for your help. I tried the first version as it matched more the Weka version. It appears that when i run the script to my data RStudio hangs and i have to Force Quit RStudio. My dataset is not that big : It has 90 cases and 15 features so maybe RStudio cannot deal with many variables being displayed at the same time. Is it possible to use the standard R Graphics for achieving this result? Commented Nov 14, 2011 at 15:24
• It works for me (RStudio 0.95.162), after I added 10 binary variables to the above artificial dataset. It takes some time to display the results, though. I can certainly update my post showing the base version, but I wonder why it is not working with you. Did you try in a simple R console?
– chl
Commented Nov 14, 2011 at 15:46
• I have no idea what is going on. I do have the same problems in RStudio but when i tried a simple R session and loaded the library i got the following message > library(Hmisc) Error in dyn.load(file, DLLpath = DLLpath, ...) : unable to load shared object '/Library/Frameworks/R.framework/Versions/2.13/Resources/library/Hmisc/libs/i386/Hmisc.so': Anyway thank you for your help Commented Nov 14, 2011 at 16:14
• You need to reinstall your package. (You can remove from the Finder directly, or using a terminal; then reinstall either the source or binary.) In the meantime, you can replace cut2 by cut (you'll have to indicate to partition the values by quartiles).
– chl
Commented Nov 14, 2011 at 16:43

Give a bit more detail & someone may give you a sample script, but in principle, you can address each column within your dataframe as frame[n] rather than frame\$column. Therefore, once you have a function which performs your design analysis, in this case a lattice, you can enclose it in a for loop and perform your analysis function with the current value of n.

• i have added an example data frame on my original question Commented Nov 14, 2011 at 8:22