1
$\begingroup$

I'm trying to figure out, how to best deal with an "other" group or how to create one. I'm using R and ggplot2.

Data

As an example: I'm analyzing the german Bundestagswahl (general election, every four years). There are at least 38 parties, that voters could vote for in 2009 (see bundeswahlleiter.de for numbers). Let's say, that I have an mysql database bundestagswahl with a column party and a column votes. Now I want to do some plots using ggplot.

Normally I would write a sql query with votes per party. Next I would tell ggplot2 to draw a geom_bar. This would draw me at least 38 bars.

Now my question

How can I create an "other" group, e.g. all parties, which have less then 5% of all votes to not clutter up the graph? This way I would have only 5 bars (=less clutter).

Of course I could write my sql-query to ignore parties, that have not at least 5%, but this way my counts wouldn't sum up to 100%. Over 6 % of all votes went to parties, which didn't made it into the parlament.

How would you do it? Write another sql query? Or using reshape? Or some other way?

Update

To make it a bit clearer, what I want to do, here is a fake dataset of six parties (names A, B, C, D, E and F) and there number of votes:

> party <- c("A", "B", "C", "D", "E", "F")
> votes <- c(1000, 2000, 5, 1500, 15, 20)
> df <- data.frame(party, votes)
> df
  party votes
1     A  1000
2     B  2000
3     C     5
4     D  1500
5     E    15
6     F    20

Now I want to do two things:

  1. relabel all parties, which have less then 100 votes to "other".
  2. add up those "other" parties to one entry.

Wanted outcome:

  party votes
1     A  1000
2     B  2000
3 other    40
4     D  1500

How do I do this? Is maybe combine_factor of the packages reshape an option?

$\endgroup$
3
  • 1
    $\begingroup$ perhaps I am missing something but why can't you determine, in R, which groups have frequencies of less than 5% and then relabel them all as 'other' and re-calculate the frequencies? $\endgroup$
    – Macro
    Commented Aug 15, 2011 at 19:25
  • $\begingroup$ @Macro: That's probably the answer: how would I relabel groups inside my dataframe? $\endgroup$
    – apepper
    Commented Aug 16, 2011 at 7:50
  • $\begingroup$ @Kevin It is already answered, so there is no sense in moving it. $\endgroup$
    – user88
    Commented Aug 16, 2011 at 18:15

2 Answers 2

3
$\begingroup$

Here's how I would probably approach the problem:

df <- within(df, other.group <- ifelse(votes > 100, as.character(party), "Other"))
df <- within(df, relevel(factor(other.group), "Other"))

ggplot(df, aes(other.group, votes)) + geom_bar(stat = "identity")
$\endgroup$
2
$\begingroup$

This will first assign "other" to any group with less then 5% of the votes and then give you the aggregated totals. The non-"other" groups are just their original values, while the "other" group gets summed.

df$party2 <- ifelse(df$votes/sum(df$votes) < 0.05, 
                    "other", 
                    as.character(df$party))
df.aggr <- aggregate(votes ~ party2, data = df, FUN = sum)

Which gives:

  party2 votes
1      A  1000
2      B  2000
3      D  1500
4  other    40
$\endgroup$
1
  • $\begingroup$ I think it should be aggr instead of df.aggr. Other then that, this works great. $\endgroup$
    – apepper
    Commented Aug 16, 2011 at 12:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.