Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

organization chart triangle plot

I would like to create a triangle plot with organization structure (hierarchy) showing the number of employees at each level in different companies.

Here is some example data:

mylabd <- data.frame (company = rep(c("A", "B", "C"), each = 7),
skillsDg = rep(c("Basic", "HighSc", "Undgd", "MAST", "PHD", "EXPD", "EXECT"), 3),
number = c(200, 100, 40, 30, 10, 0, 0,
           220, 110, 35, 10, 0, 4, 1,
           140, 80, 120, 50, 52, 52, 3)
           )
   company skillsDg number
1        A    Basic    200
2        A   HighSc    100
3        A    Undgd     40
4        A     MAST     30
5        A      PHD     10
6        A     EXPD      0
7        A    EXECT      0
8        B    Basic    220
9        B   HighSc    110
10       B    Undgd     35
11       B     MAST     10
12       B      PHD      0
13       B     EXPD      4
14       B    EXECT      1
15       C    Basic    140
16       C   HighSc     80
17       C    Undgd    120
18       C     MAST     50
19       C      PHD     52
20       C     EXPD     52
21       C    EXECT      3

The objective is to reflect how different companies hire different skilled or degree workers.

The hypothetical figure is this (although color fill is not perfect). enter image description here The idea is that the width of line at each stage is proportional and then lines are connected. If there is no category in subsequent level, it will not be connected (like in company B). I couldn't find a program that can do this and neither could figure out. Any idea ?

Edit:

I do not alot about R, but here is my how my idea is shaping. It divides each line segment into two from a point to make it symetical. The drawn horizontal lines are then connected.

enter image description here

like image 748
rdorlearn Avatar asked Dec 21 '12 15:12

rdorlearn


3 Answers

I don't know of any function doing that but here is one from scratch:

my1 <- data.frame (company = rep(c("A", "B", "C"), each = 7), skillsDg = rep(c("Basic", "HighSc", "Undgd", "MAST", "PHD", "EXPD", "EXECT"), 3), number = c(200, 100, 40, 30, 10, 0, 0, 220, 110, 35, 10, 0, 4, 1, 140, 80, 120, 50, 52, 52, 3) )

my2 <- split(my1,my1$company) #split your dataframe into a list where each element is a company
# The next line create the layout
layout(matrix(1:(length(my2)+1), nrow=1), width=c(1,rep(4,length(my2))))
# Then we draw the x-axis:
par(mar=c(3,0,3,0))
plot(NA,axes=F, xlim=c(0,1),ylim=c(1,nlevels(my1$skillsDg)))
axis(side=4,tick=F,labels=unique(my1$skillsDg),
     at=seq_along(unique(my1$skillsDg)), las=2, line=-4)
# Then we apply a graphing function to each company:
lapply(my2,function(x){
    par(mar=c(3,0,3,0))
    plot(NA, xlim=c(-max(my1$number),max(my1$number)), 
             ylim=c(1,nlevels(my1$skillsDg)),axes=F)
    title(sub=x$company[1],line=1)
    abline(h=seq_along(x$skillsDg), col="grey80")
    polygon(x=c(x$number,rev(-1*x$number)), 
            y=c(seq_along(x$skillsDg),rev(seq_along(x$skillsDg))), 
            col=as.numeric(x$company))
    })

enter image description here

Edit: You can of course add whatever you want inside the graphing function in lapply (but in some case it might mean changing a little the dimensions of the graph):

layout(matrix(1:(length(my2)+1), nrow=1), width=c(1,rep(4,length(my2))))
par(mar=c(3,0,3,0))
plot(NA,axes=F, xlim=c(0,1),ylim=c(1,nlevels(my1$skillsDg)))
axis(side=4,tick=F,labels=unique(my1$skillsDg),
    at=seq_along(unique(my1$skillsDg)), las=2, line=-4)
lapply(my2,function(x){
    par(mar=c(3,0,3,0))
    plot(NA, xlim=c(-max(my1$number)-50,max(my1$number)+50), 
        ylim=c(1,nlevels(my1$skillsDg)),axes=F)
    title(sub=x$company[1],line=1)
    abline(h=seq_along(x$skillsDg), col="grey80")
    text(x=x$number+5, y=seq_along(x$skillsDg)+.1, label=x$number, pos=4)
    polygon(x=c(x$number,rev(-1*x$number)), 
        y=c(seq_along(x$skillsDg),rev(seq_along(x$skillsDg))), 
        col=as.numeric(x$company))
    })

enter image description here

like image 105
plannapus Avatar answered Nov 01 '22 20:11

plannapus


Using the grid package, we can have someting like this:

enter image description here

mylabd <- data.frame (company = rep(c("A", "B", "C"), each = 7),
                      skillsDg = rep(c("Basic", "HighSc", "Undgd", "MAST", "PHD", "EXPD", "EXECT"), 3),
                      number = c(200, 100, 40, 30, 10, 0, 0,
                                 220, 110, 35, 10, 0, 4, 1,
                                 140, 80, 120, 50, 52, 52, 3)
)



## to comapre we need o have the same scales for all organizations
nskills <- nlevels(mylabd$skillsDg)
ncompany <- nlevels(mylabd$company)
barYscale <- c(0,  nskills) * 1.05
barXscale <- c(0, max(mylabd$number) )* 1.05
## the global scene
vp <- plotViewport(c(5, 4, 4, 1),
                   yscale = barYscale,
                   layout = grid.layout(nrow=1,ncol=nbars))

pushViewport(vp)
grid.rect()
grid.yaxis(at=c(1:nlevels(mylabd$skillsDg)),label=unique(mylabd$skillsDg))
grid.grill()

## split data by companya
data.splitted <- split(mylabd,f=mylabd$company)
lapply(1:3,function(company){

  x <- data.splitted[[company]]
  vv <- x$number
  companyName <- unique(x$company)

  pushViewport(viewport(layout.pos.col=company,    
                        xscale = barXscale,
                        yscale = barYscale))
  grid.rect()
 # grid.xaxis(at= mean(x$number),label = companyName)
  grid.xaxis()
  grid.polygon(x  = unit.c(unit(0.5,'npc')-unit(vv/2,'native'),
                           unit(0.5,'npc')+unit(rev(vv)/2,'native')),
               y  = unit.c(unit(1:nmeasures,'native'),
                           unit(rev(1:nmeasures),'native')),
               gp=gpar(fill = rainbow(nmeasures)[company]))
  grid.polygon(x  = unit.c(unit(0.5,'npc')-unit(vv/2,'native'),
                           unit(0.5,'npc')+unit(rev(vv)/2,'native')),
               y  = unit.c(unit(1:nmeasures,'native'),
                           unit(rev(1:nmeasures),'native')),
               id = c(1:nmeasures,rev(1:nmeasures)),
               gp=gpar(fill = NA))

  grid.text( x = unit(0.5,'npc'),
             y = unit(0.5,'native'),
             label = unique(x$company))

  popViewport()

})

popViewport()
like image 45
agstudy Avatar answered Nov 01 '22 22:11

agstudy


Different chart than you asked for, but an attempt to follow some common visualization principles:

library(ggplot2)
mylabd$skillsDg <- factor(mylabd$skillsDg, levels = c("Basic", "HighSc", "Undgd", "MAST", "PHD", "EXPD", "EXECT"))
p <- ggplot(data=mylabd, aes(x=skillsDg, y=number, fill = skillsDg))
p <- p + geom_bar(stat = "identity") + coord_flip()
p <- p + facet_wrap( ~ company, ncol = 1, nrow=3)
plot(p)

enter image description here

like image 1
Isaiah Avatar answered Nov 01 '22 21:11

Isaiah