Search code examples
rplotscale

How to scale points in R plot?


I have 40 pairs of birds with each male and female scored for their colour. The colour score is a categorical variable (range of 1 to 9). I would like to plot the frequency of the number of males and female pairs colour combinations. I have to created a 'table' with the number of each combination (1/1, 1/2, 1/3, ... 9/7, 9/8, 9/9), then converted it to a vector called 'Colour_Count'. I would like to use 'Colour_Count' for the 'cex' parameter in the 'plot' to scale the size of each combination of colours. This does not work because of the order the data is read from the table. How do I create a vector with the frequency of each colour combination to scale my plot points?

See data and code below:

## Dataset pairs of males and females and their colour classes
Pair_Colours <- structure(list(Male = c(7, 6, 4, 6, 8, 8, 5, 6, 6, 8, 6, 6, 5, 
7, 9, 5, 8, 7, 5, 5, 4, 6, 7, 7, 3, 6, 5, 4, 7, 4, 3, 9, 4, 4, 
4, 4, 9, 6, 6, 6), Female = c(9, 8, 8, 9, 3, 6, 8, 5, 8, 9, 7, 
3, 6, 5, 8, 9, 7, 3, 6, 4, 4, 4, 8, 8, 6, 7, 4, 2, 8, 9, 5, 6, 
8, 8, 4, 4, 5, 9, 7, 8)), .Names = c("Male", "Female"), class = "data.frame", row.names = c(NA, 
40L))

Pair_Colours[] <- as.data.frame(lapply(Pair_Colours, factor, levels=1:9))

## table of pair colour values (colours 1 to 9 - categoricial variable)
table(Pair_Colours$Male, Pair_Colours$Female)

Colour_Count <-  as.vector(table(Pair_Colours$Male, Pair_Colours$Female)) #<- the problem occurs here

## plot results to visisually look for possible assortative mating by colour
op<-par(mfrow=c(1,1), oma=c(2,4,0,0), mar=c(4,5,1,2), pty = "s")
plot(1,1, xlim = c(1, 9), ylim = c(1, 9), type="n", xaxt = "n", yaxt = "n", las=1, bty="n", cex.lab = 1.75, cex.axis = 1.5, main = NULL, xlab = "Male Colour", ylab = "Female Colour", pty = "s")
axis(1, at = seq(1, 9, by = 1), labels = T, cex.lab = 1.5, cex.axis = 1.5, tick = TRUE, tck = -0.015, lwd = 1.25, lwd.ticks = 1.25)
axis(2, at = seq(1, 9, by = 1), labels = T, cex.lab = 1.5, cex.axis = 1.5, tick = TRUE, tck = -0.015, lwd = 1.25, lwd.ticks = 1.25, las =2)
points(Pair_Colours$Male, Pair_Colours$Female, pch = 21, cex = Colour_Count, bg = "darkgray", col = "black", lwd = 1)

Solution

  • You can summarise your data with function ddply() of library plyr and then use this new data frame to plot your data. Counts are in column V1 of new data frame.

    library(plyr)
    df<-ddply(Pair_Colours,.(Male,Female),nrow)
    df
       Male Female V1
    1     3      5  1
    2     3      6  1
    3     4      2  1
    4     4      4  3
    
    points(df$Male, df$Female, pch = 21, cex = df$V1, 
                   bg = "darkgray", col = "black", lwd = 1)
    

    UPDATE - solution using aggregate

    Other possibility is to use function aggregate(). First, add new column N that contains just values 1. Then with aggregate() sum N values for each Male and Female combination.

    Pair_Colours$N<-1
    aggregate(N~Male+Female,data=Pair_Colours,FUN=sum)
    
       Male Female N
    1     4      2 1
    2     6      3 1
    3     7      3 1
    4     8      3 1
    5     4      4 3
    

    enter image description here