deschen
deschen

Reputation: 10996

R plot function - axes for a line chart

assume the following frequency table in R, which comes out of a survey:

      1  2  3  4  5  8
  m   5 16  3 16  5  0
  f  12 25  3 10  3  1
  NA  1  0  0  0  0  0

The rows stand for the gender of the survey respondent (male/female/no answer). The colums represent the answers to a question on a 5 point scale (let's say: 1= agree fully, 2 = agree somewhat, 3 = neither agree nor disagree, 4= disagree somewhat, 5 = disagree fully, 8 = no answer).

The data is stored in a dataframe called "slm", the gender variable is called "sex", the other variable is called "tv_serien".

My problem is, that I don't find a (in my opinion) proper way to create a line chart, where the x-axis represents the 5-point scale (plus the don't know answers) and the y-axis represents the frequencies for every point on the scale. Furthemore I want to create two lines (one for males, one for females).

My solution so far is the following:

  1. I create a plot without plotting the "content" and the x-axis:

    plot(slm$tv_serien, xlim = c(1,6), ylim = c(0,100), type = "n", xaxt = "n")
    

The problem here is that it feels like cheating to specify the xlim=c(1,6), because the raw scores of slm$tv_serienare 100 values. I tried also to to plot the variable via plot(factor(slm$tv_serien)...), but then it would still create a metric scale from 1 to 8 (because the dont know answer is 8).

So my first question is how to tell R that it should take the six distinct values (1 to 5 and 8) and take that as the x-axis?

  1. I create the new x axis with proper labels:

    axis(1, 1:6, labels = c("1", "2", "3", "4", "5", "DK"))
    

At least that works pretty well. ;-)

  1. Next I create the line for the males:

    lines(1:5, table(slm$tv_serien[slm$sex == 1]), col = "blue")
    

The problem here is that there is no DK (=8) answer, so I manually have to specify x = 1:5 instead of 1:6 in the "normal" case. My question here is, how to tell R to also draw the line for nonexisting values? For example, what would have happened, if no male had answered with 3, but I want a continuous line?

  1. At last I create the line for females, which works well:

    lines(1:6, table(slm$tv_serien[slm$sex == 2], col = "red")
    

To summarize:

Thanks for your help!

PS: Attached you find the current plot for the abovementiond functions.

PPS: I tried to make a list from "1." to "4." but it seems that every new list element started again with "1.". Sorry.

line chart

Upvotes: 0

Views: 320

Answers (1)

jlhoward
jlhoward

Reputation: 59335

Edit: Response to OP's comment.

This directly creates a line chart of OP's data. Below this is the original answer using ggplot, which produces a far superior output.

Given the frequency table you provided,

df <- data.frame(t(freqTable))        # transpose (more suitable for plotting)
df <- cbind(Response=rownames(df),df) # add row names as first column

plot(as.numeric(df$Response),df$f,type="b",col="red", 
     xaxt="n", ylab="Count",xlab="Response")
lines(as.numeric(df$Response),df$m,type="b",col="blue")
axis(1,at=c(1,2,3,4,5,6),labels=c("Str.Agr.","Sl.Agr","Neither","Sl.Disagr","Str.Disagr","NA"))

Produces this, which seems like what you were looking for.

Original Answer:

Not quite what you asked for, but converting your frequency table to a data frame, df

df <- data.frame(freqTable)
df <- cbind(Gender=rownames(df),df)    # append rownames (Gender)
df <- df[-3,]                          # drop unknown gender
df
#   Gender X1 X2 X3 X4 X5 X8
# m      m  5 16  3 16  5  0
# f      f 12 25  3 10  3  1

df <- df[-3,]     # remove unknown gender column

library(ggplot2)
library(reshape2)
gg=melt(df)

labels <- c("Agree\nFully","Somewhat\nAgree","Neither Agree\nnor Disagree","Somewhat\nDisagree","Disagree\nFully", "No Answer")
ggp <- ggplot(gg,aes(x=variable,y=value))
ggp <- ggp + geom_bar(aes(fill=Gender), position="dodge", stat="identity")
ggp <- ggp + scale_x_discrete(labels=labels)
ggp <- ggp + theme(axis.text.x = element_text(angle=90, vjust=0.5))
ggp <- ggp + labs(x="", y="Frequency")
ggp

Produces this:

Or, this, which is much better:

ggp + facet_grid(Gender~.)

Upvotes: 1

Related Questions