问题
I am trying to create a pie chart with my following data in R:
2009 2010
US 10 12
UK 13 14
Germany 18 11
China 9 8
Malaysia 7 15
Others 13 15
The command I am using is:
slices<-c(10,13,18,9,7,13,12,14,11,8,15,15)
lbls <- c("US","UK","Germany","China", "Malaysia", "Others","US","UK","Germany","China", "Malaysia", "Others")
pct <- round(slices/sum(slices)*100)
lbls <- paste(lbls,"%",sep="")
lbls <- paste(lbls, pct)
pie(slices,labels = lbls, col=rainbow(length(lbls)), main="Pie Chart of Countries")
The figure that I am getting
Now how can I configure the graph so that the countries have same colour scheme? and they follow the same order in two halves, like first it should be US and the UK and so on.
Two simplify the question I want to make two piecharts in one piechart, where one half of piechart represents 2009 and the other half 2010.
kindly help.
Thank you
回答1:
This might work. At least the two halves have the same color scheme. I am not sure what you mean by the same order.
slices<-c(10,13,18,9,7,13,12,14,11,8,15,15)
pct <- round(slices/sum(slices)*100)
lbls <- c("US","UK","Germany","China", "Malaysia", "Others","US","UK","Germany","China", "Malaysia", "Others")
lbls <- paste(lbls,"%",sep="")
lbls <- paste(lbls, pct)
col <- c("yellow", "orange", "red", "purple", "blue", "green", "yellow", "orange", "red", "purple", "blue", "green")
pie(slices,labels = lbls, main="Pie Chart of Countries", col = col)
You can shorten the col
code with
col <- rep(c("yellow", "orange", "red", "purple", "blue", "green"),2)
I am not certain what you want regarding the two halves. If you want to standardize the percentages to 50% for each half this might work:
a <- c(7, 9, 12, 6, 5, 9)
a2 <- (a/sum(a)) * 50
a2
# [1] 7.291667 9.375000 12.500000 6.250000 5.208333 9.375000
b <- c(8, 10, 8, 6, 10, 10)
b2 <- (b/sum(b)) * 50
b2
# [1] 7.692308 9.615385 7.692308 5.769231 9.615385 9.615385
pct <- round(c(a2,b2),2)
pct
回答2:
lbls0 <- c("US","UK","Germany","China", "Malaysia", "Others","US","UK","Germany","China", "Malaysia", "Others")
pct <- round(slices/sum(slices)*100)
lbls <- paste(lbls,"%",sep="")
lbls <- paste(lbls, pct)
pie(slices,labels = lbls, col=rainbow(length(lbls)),
main="Pie Chart of Countries")
nlbl <- length(lbls)
yrs <- rep(2009:2010,each=nlbl/2)
xlbls <- sprintf("%s (%d) %d%%",lbls0,yrs,pct)
pie(slices,labels = xlbls, col=rep(rainbow(nlbl/2),2),
main="Pie Chart of Countries")
Would you be willing to consider a form of visualization that makes it easier to make quantitative comparisons?
library(ggplot2); theme_set(theme_bw())
dd <- data.frame(lbls0,yrs,slices,pct)
dd$lbls0 <- reorder(dd$lbls0,-dd$slices)
ggplot(dd,aes(x=lbls0,y=slices,fill=lbls0))+
geom_bar(aes(alpha=factor(yrs)),
stat="identity",position=position_dodge(width=1))+
scale_alpha_discrete(range=c(0.7,1.0))+
geom_text(aes(label=paste0(pct,"%"),
group=interaction(lbls0,yrs)),hjust=-0.2,
position=position_dodge(width=1))+
coord_flip()+
expand_limits(y=20)+labs(x="",y="total")
If you're more interested in comparisons among countries within years rather than among years within countries, you could skip the scale_alpha
stuff and use facet_wrap(~yrs)
...
回答3:
You can solve this with the help of the reshape2
package:
# reading the data
df <- read.table(header=TRUE, text="Country 2009 2010
US 10 12
UK 13 14
Germany 18 11
China 9 8
Malaysia 7 15
Others 13 15")
# setting the column names correct
colnames(df) <- c("Country","2009","2010")
# reshaping the dataframe
require(reshape2)
df2 <- melt(df, id="Country")
# creating the plot
pie(df2$value, labels=paste0(df2$Country," (",df2$variable,") ",df2$value,"%"),
col=rainbow(length(levels(df2$Country))), main="Pie Chart of Countries")
which gives:
For a variation on the year-labels, you can also use:
pie(df2$value, labels=paste0(df2$Country," ",df2$value,"%"),
col=rainbow(length(levels(df2$Country))), main="Pie Chart of Countries")
mtext("2009",side=3)
mtext("2010",side=1)
which gives:
As @BenBolker said, pie-charts are not a very good way of presenting data. It's worth quoting the help page ?pie
were this is recognized as well:
Pie charts are a very bad way of displaying information. The eye is good at judging linear measures and bad at judging relative areas. A bar chart or dot chart is a preferable way of displaying this type of data.
Cleveland (1985), page 264: “Data that can be shown by pie charts always can be shown by a dot chart. This means that judgements of position along a common scale can be made instead of the less accurate angle judgements.” This statement is based on the empirical investigations of Cleveland and McGill as well as investigations by perceptual psychologists.
回答4:
Here is another solution which was similar to my answer here
slices <- c(10,13,18,9,7,13,12,14,11,8,15,15)
lbls <- c("US","UK","Germany","China", "Malaysia", "Others","US","UK","Germany","China", "Malaysia", "Others")
pct <- round(slices/sum(slices)*100)
lbls <- paste(lbls,"%",sep="")
lbls <- paste(lbls, pct)
dat <- data.frame(year = rep(c(2009, 2010), each = 6), lbls, slices)
dat$total <- with(dat, ave(slices, year, FUN = sum))
plot.new()
par(new = TRUE)
pie(dat$slices, border = NA, radius = 1,
col = rainbow(length(lbls) / 2), labels = lbls,
main = 'Pie Chart of Countries')
par(new = TRUE)
c2 <- c('grey50', 'grey75')[factor(dat$year)]
pie(dat$slices, border = c2, radius = .7, col = c2, labels = NA)
text(0, c(.3, -.3), 2009:2010)
来源:https://stackoverflow.com/questions/23984035/putting-two-pie-charts-in-one