I'm using the jbryer/likert
package to plot Likert data.
Consider the response table, called items
—here, A
, B
, and so on are the column names, not part of the data:
A B C D
5 4 5 4
3 3 3 4
2 2 2 2
2 2 2 3
5 3 6 7
3 3 5 4
And the following code:
choices = c("Very low", "Low", "Rather low", "Neither low nor high", "Rather high", "High", "Very high")
for(i in 1:ncol(items)) {
items[,i] = factor(items[,i], levels=1:7, labels=choices, ordered=TRUE)
}
Now, we transform this into the likert
data and plot it, which overrides the built-in plot function with one that uses ggplot
:
plot(likert(items), ordered=FALSE)
This gives me:
Cool. All ordered. But A
, B
, etc. are not meaningful as descriptors for the conditions, and I'd like to override them:
names(items) = c("LT", "ST", "SemTag", "SemTagContext")
Which gives me the wrong order:
See how ST
comes first, although it's the name for B
? My ordering got changed to B
, D
, C
, A
.
How can I make it preserve the order and return the bars in D
, C
, B
, A
—or, with my new group names: SemTagContext
, SemTag
, ST
, LT
?
Note: The data table above is shortened. The bar widths in the plot don't reflect this short data example, but the full dataset I have. The problem is the same though.
I decided to re-implement this myself, as jon suggested:
# additional requirements
library(ggplot2)
library(reshape2)
library(RColorBrewer)
# create summary table
table_summary = likert(items)
# reshape results
results = melt(table_summary$results, id.vars='Item')
# reorder results
results$Item = factor(results$Item, levels=c("LT", "ST", "SemTag", "SemTagContext"))
# some defaults
ymin = 0
text.size = 3
ggplot(results, aes(y=value, x=Item, group=Item)) +
geom_bar(stat='identity', aes(fill=variable)) +
ylim(c(-5,105)) +
coord_flip() +
scale_fill_manual('Response', values=brewer.pal(7, "RdYlGn"),
breaks=levels(results$variable),
labels=levels(results$variable)) +
geom_text(data=table_summary$summary, y=ymin, aes(x=Item,
label=paste(round(low), '%', sep='')),
size=text.size, hjust=1) +
geom_text(data=table_summary$summary, y=100, aes(x=Item,
label=paste(round(high), '%', sep='')),
size=text.size, hjust=-.2) +
ylab('Percentage') + xlab('')
This produces the correct order:
You can do this using the group.order parameter to specify the order. Use the names() function to obtain the names of the columns.
plot(likert_var, group.order=names(results))
I added a pull request to Jason Bryer's package that adds fullname attributes to the columns, which are then used when you plot. Detailed writeup here http://reganmian.net/blog/2013/10/02/likert-graphs-in-r-embedding-metadata-for-easier-plotting/
Given that addition, you can do
db <- likert_add_fullnames(db, c(
"X7"="Do you use sites like Facebook, Twitter, or GPlus?",
"X8"="Do you participate in online communities organised around your interests?
(could be juggling, cooking, sports or academics, for example)?",
"X10"="Do you know of online communities relevant to your discipline or the
courses you are taking now?"))
...
and then these names will be reflected when you plot.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With