Dimitri Liakhovitski
2009-May-18 18:47 UTC
[R] Barchart in lattice - wrong order of groups, data labels on top of each other, and a legend question
Hello! I have a question about my lattice barchart that I am trying to build in Section 3 below. I can't figure out a couple of things: 1. When I look at the dataframe "test" that I am trying to plot, it looks right to me (the group "Total" is always the first out of 5). However, in the chart it is the last. Why? 2. How can I make sure the value labels (on y) are not sitting on top of each other but on top of the respective bar? 3. Is there any way to make the legend group items horizontally as opposed to now (vertically - taking up too much space) Thanks a lot! Dimitri ### Section 1: generates my data set "data" - just run: ##### N<-100 myset1<-c(1,2,3,4,5) probs1<-c(.05,.10,.15,.40,.30) myset2<-c(0,1) probs2<-c(.65,.30) myset3<-c(1,2,3,4,5,6,7) probs3<-c(.02,.03,.10,.15,.20,.30,.20) group<-unlist(lapply(1:4,function(x){ out<-rep(x,25) return(out) })) set.seed(1) a<-sample(myset1, N, replace = TRUE,probs1) a[which(rbinom(100,2,.01)==1)]<-NA set.seed(12) b<-sample(myset1, N, replace = TRUE,probs1) b[which(rbinom(100,2,.01)==1)]<-NA set.seed(123) c<-sample(myset2, N, replace = TRUE,probs2) set.seed(1234) d<-sample(myset2, N, replace = TRUE,probs2) set.seed(12345) e<-sample(myset3, N, replace = TRUE,probs3) e[which(rbinom(100,2,.01)==1)]<-NA set.seed(123456) f<-sample(myset3, N, replace = TRUE,probs3) f[which(rbinom(100,2,.01)==1)]<-NA data<-data.frame(group,a=a,b=b,c=c,d=d,e=e,f=f) data["group"]<-lapply(data["group"],function(x) { x[x %in% 1]<-"Group 1" x[x %in% 2]<-"Group 2" x[x %in% 3]<-"Group 3" x[x %in% 4]<-"Group 4" return(x) }) data$group<-as.factor(data$group) lapply(data,table,exclude=NULL) tables<-lapply(data,function(x){ out<-table(x) out<-prop.table(out) out<-round(out,3)*100 return(out) }) str(tables[2]) ##### Section 2: Generating a list of tables with percentages to be plotted in barcharts - just run: ##### listoftables<-list() for(i in 1:(length(data)-1)) { listoftables[[i]]<-data.frame() } for(i in 1:length(listoftables)) { total<-table(data[[i+1]]) groups<-table(data[[1]],data[[i+1]]) total.percents<-as.data.frame(t(as.vector(round(total*100/sum(total),1)))) groups.percents<-as.data.frame(t(apply(groups,1,function(x){ out<-round(x*100/sum(x),1) return(out) }))) names(total.percents)<-names(groups.percents) final.table<-rbind(total.percents,groups.percents) row.names(final.table)[1]<-"Total" final.table<-as.matrix(final.table) listoftables[[i]]<-final.table } names(listoftables)<-names(data)[2:(length(listoftables)+1)] ### Section 3 - building the graph for the very first table of the "listoftables" ### library(lattice) i<-1 test <- data.frame(Group = rep(row.names(listoftables[[i]]),5), a rep(1:5,each=5),Percentage = as.vector(listoftables[[i]])) par.settings=trellis.par.set(reference.line = list(col = "gray", lty ="dotted")) barchart(Percentage~a, test, groups = Group, horizontal = F, auto.key = list(points = FALSE, rectangles = TRUE, space "bottom"),ylim = c(0,50), panel = function(y,x,...) { panel.grid(h = -1, v = -1) panel.barchart(x, y, ...) ltext(x, y, labels=round(y,0),cex=.7,col="black",font=2,pos=3) }) -- Dimitri Liakhovitski MarketTools, Inc. Dimitri.Liakhovitski at markettools.com
Deepayan Sarkar
2009-May-19 23:53 UTC
[R] Barchart in lattice - wrong order of groups, data labels on top of each other, and a legend question
On Mon, May 18, 2009 at 11:47 AM, Dimitri Liakhovitski <ld7631 at gmail.com> wrote:> Hello! > I have a question about my lattice barchart that I am trying to build > in Section 3 below. I can't figure out a couple of things: > 1. When I look at the dataframe "test" that I am trying to plot, it > looks right to me (the group "Total" is always the first out of 5). > However, in the chart it is the last. Why? > 2. How can I make sure the value labels (on y) are not sitting on top > of each other but on top of the respective bar? > 3. Is there any way to make the legend group items horizontally as > opposed to now (vertically - taking up too much space)For 1 and 3, use auto.key = list(points = FALSE, rectangles = TRUE, reverse.rows = TRUE, columns = 2, space = "bottom")>From ?xyplot (under 'key'):'reverse.rows' logical, defaulting to 'FALSE'. If 'TRUE', all components are reversed _after_ being replicated (the details of which may depend on the value of 'rep'). This is useful in certain situations, e.g. with a grouped 'barchart' with 'stack = FALSE' with the categorical variable on the vertical axis, where the bars in the plot will usually be ordered from bottom to top, but the corresponding legend will have the levels from top to bottom (unless, of course, 'reverse.rows TRUE'). Note that in this case, unless all columns have the same number or rows, they will no longer be aligned. 'columns' the number of columns column-blocks the key is to be divided into, which are drawn side by side. 2 is hard with a simple custom panel function, because you need to replicate some fairly involved calculations that are performed in panel.barchart. Your best bet is to start with a copy of panel.barchart, and then add calls to panel.text at suitable places. -Deepayan> Thanks a lot! > Dimitri > > ### Section 1: generates my data set "data" - just run: ##### > > N<-100 > myset1<-c(1,2,3,4,5) > probs1<-c(.05,.10,.15,.40,.30) > myset2<-c(0,1) > probs2<-c(.65,.30) > myset3<-c(1,2,3,4,5,6,7) > probs3<-c(.02,.03,.10,.15,.20,.30,.20) > > group<-unlist(lapply(1:4,function(x){ > ? ? ? ?out<-rep(x,25) > ? ? ? ?return(out) > })) > set.seed(1) > a<-sample(myset1, N, replace = TRUE,probs1) > a[which(rbinom(100,2,.01)==1)]<-NA > set.seed(12) > b<-sample(myset1, N, replace = TRUE,probs1) > b[which(rbinom(100,2,.01)==1)]<-NA > set.seed(123) > c<-sample(myset2, N, replace = TRUE,probs2) > set.seed(1234) > d<-sample(myset2, N, replace = TRUE,probs2) > set.seed(12345) > e<-sample(myset3, N, replace = TRUE,probs3) > e[which(rbinom(100,2,.01)==1)]<-NA > set.seed(123456) > f<-sample(myset3, N, replace = TRUE,probs3) > f[which(rbinom(100,2,.01)==1)]<-NA > data<-data.frame(group,a=a,b=b,c=c,d=d,e=e,f=f) > data["group"]<-lapply(data["group"],function(x) { > ? ? ? ?x[x %in% 1]<-"Group 1" > ? ? ? ?x[x %in% 2]<-"Group 2" > ? ? ? ?x[x %in% 3]<-"Group 3" > ? ? ? ?x[x %in% 4]<-"Group 4" > ? ? ? ?return(x) > }) > data$group<-as.factor(data$group) > lapply(data,table,exclude=NULL) > > tables<-lapply(data,function(x){ > ? ? ? ?out<-table(x) > ? ? ? ?out<-prop.table(out) > ? ? ? ?out<-round(out,3)*100 > ? ? ? ?return(out) > }) > str(tables[2]) > > ##### Section 2: Generating a list of tables with percentages to be > plotted in barcharts - just run: ##### > > listoftables<-list() > for(i in 1:(length(data)-1)) { > ?listoftables[[i]]<-data.frame() > } > for(i in 1:length(listoftables)) { > ? ?total<-table(data[[i+1]]) > ? ?groups<-table(data[[1]],data[[i+1]]) > ? ?total.percents<-as.data.frame(t(as.vector(round(total*100/sum(total),1)))) > ? ?groups.percents<-as.data.frame(t(apply(groups,1,function(x){ > ? ? ?out<-round(x*100/sum(x),1) > ? ? return(out) > ?}))) > ?names(total.percents)<-names(groups.percents) > ?final.table<-rbind(total.percents,groups.percents) > ?row.names(final.table)[1]<-"Total" > ?final.table<-as.matrix(final.table) > ?listoftables[[i]]<-final.table > } > names(listoftables)<-names(data)[2:(length(listoftables)+1)] > > > ### Section 3 - building the graph for the very first table of the > "listoftables" ### > library(lattice) > i<-1 > test <- data.frame(Group = rep(row.names(listoftables[[i]]),5), a > rep(1:5,each=5),Percentage = as.vector(listoftables[[i]])) > par.settings=trellis.par.set(reference.line = list(col = "gray", lty ="dotted")) > barchart(Percentage~a, test, groups = Group, horizontal = F, > auto.key = list(points = FALSE, rectangles = TRUE, space > "bottom"),ylim = c(0,50), > ? ?panel = function(y,x,...) { > ? ?panel.grid(h = -1, v = -1) > ? ?panel.barchart(x, y, ...) > ? ?ltext(x, y, labels=round(y,0),cex=.7,col="black",font=2,pos=3) > }) > > > -- > Dimitri Liakhovitski > MarketTools, Inc. > Dimitri.Liakhovitski at markettools.com > > ______________________________________________ > R-help at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >