R:使用ggplot2将百分比作为标签的饼图

pes*_*bar 10 r labels ggplot2 pie-chart

从数据框架中,我想绘制五个类别的饼图,其百分比作为同一图表中的标签,从最高到最低顺序,顺时针方向.

我的代码是:

League<-c("A","B","A","C","D","E","A","E","D","A","D")
data<-data.frame(League) # I have more variables 

p<-ggplot(data,aes(x="",fill=League))
p<-p+geom_bar(width=1)
p<-p+coord_polar(theta="y")
p<-p+geom_text(data,aes(y=cumsum(sort(table(data)))-0.5*sort(table(data)),label=paste(as.character(round(sort(table(data))/sum(table(data)),2)),rep("%",5),sep="")))
p
Run Code Online (Sandbox Code Playgroud)

我用

cumsum(sort(table(data)))-0.5*sort(table(data))
Run Code Online (Sandbox Code Playgroud)

将标签放在相应的部分和

label=paste(as.character(round(sort(table(data))/sum(table(data)),2)),rep("%",5),sep="")
Run Code Online (Sandbox Code Playgroud)

对于标签,这是百分比.

我得到以下输出:

Error: ggplot2 doesn't know how to deal with data of class uneval
Run Code Online (Sandbox Code Playgroud)

Gre*_*gor 10

我保留了你的大部分代码.我发现这很容易调试,省略了coord_polar...更容易看到正在发生的条形图.

主要的是将因子从最高到最低重新排序以使绘图顺序正确,然后只是使用标签位置来使它们正确.我还简化了标签的代码(你不需要as.character或者rep,并且paste0是一个快捷方式sep = "".)

League<-c("A","B","A","C","D","E","A","E","D","A","D")
data<-data.frame(League) # I have more variables 

data$League <- reorder(data$League, X = data$League, FUN = function(x) -length(x))

at <- nrow(data) - as.numeric(cumsum(sort(table(data)))-0.5*sort(table(data)))

label=paste0(round(sort(table(data))/sum(table(data)),2) * 100,"%")

p <- ggplot(data,aes(x="", fill = League,fill=League)) +
  geom_bar(width = 1) +
  coord_polar(theta="y") +
  annotate(geom = "text", y = at, x = 1, label = label)
p
Run Code Online (Sandbox Code Playgroud)

at计算是找到楔子的中心.(将它们视为堆积条形图中条形图的中心更容易,只需运行上面的图而不coord_polar需要查看线条.)at计算结果如下:

table(data)是每个组中的行数,并sort(table(data))按照它们将被绘制的顺序排列.取cumsum()的,关于彼此的顶部上堆叠时,并乘以0.5使我们有一半在堆叠(或饼图楔形的一半的宽度)的每个杆的高度为我们提供了每个条的边缘.

as.numeric()只是确保我们有一个数字向量而不是类的对象table.

从累积高度中减去半宽度可以在堆叠时为每个条形中心提供中心.但是ggplot会将底部最大的条形堆叠起来,而我们所有的条形都是sort()最小的,所以我们需要做nrow -所有事情,因为我们实际计算的是相对于条形顶部的标签位置,而不是底部.(并且,根据原始的分解数据,nrow()是总行数,因此是条的总高度.)


ale*_*yes 10

前言:我没有按自己的意愿制作饼图.

这是ggpie对包含百分比的函数的修改:

library(ggplot2)
library(dplyr)

#
# df$main should contain observations of interest
# df$condition can optionally be used to facet wrap
#
# labels should be a character vector of same length as group_by(df, main) or
# group_by(df, condition, main) if facet wrapping
#

pie_chart <- function(df, main, labels = NULL, condition = NULL) {

  # convert the data into percentages. group by conditional variable if needed
  df <- group_by_(df, .dots = c(condition, main)) %>%
    summarize(counts = n()) %>%
    mutate(perc = counts / sum(counts)) %>%
    arrange(desc(perc)) %>%
    mutate(label_pos = cumsum(perc) - perc / 2,
           perc_text = paste0(round(perc * 100), "%"))

  # reorder the category factor levels to order the legend
  df[[main]] <- factor(df[[main]], levels = unique(df[[main]]))

  # if labels haven't been specified, use what's already there
  if (is.null(labels)) labels <- as.character(df[[main]])

  p <- ggplot(data = df, aes_string(x = factor(1), y = "perc", fill = main)) +

    # make stacked bar chart with black border
    geom_bar(stat = "identity", color = "black", width = 1) +

    # add the percents to the interior of the chart
    geom_text(aes(x = 1.25, y = label_pos, label = perc_text), size = 4) +

    # add the category labels to the chart
    # increase x / play with label strings if labels aren't pretty
    geom_text(aes(x = 1.82, y = label_pos, label = labels), size = 4) +

    # convert to polar coordinates
    coord_polar(theta = "y") +

    # formatting
    scale_y_continuous(breaks = NULL) +
    scale_fill_discrete(name = "", labels = unique(labels)) +
    theme(text = element_text(size = 22),
          axis.ticks = element_blank(),
          axis.text = element_blank(),
          axis.title = element_blank())

  # facet wrap if that's happening
  if (!is.null(condition)) p <- p + facet_wrap(condition)

  return(p)
}
Run Code Online (Sandbox Code Playgroud)

例:

# sample data
resps <- c("A", "A", "A", "F", "C", "C", "D", "D", "E")
cond <- c(rep("cat A", 5), rep("cat B", 4))
example <- data.frame(resps, cond)
Run Code Online (Sandbox Code Playgroud)

就像典型的ggplot调用一样:

ex_labs <- c("alpha", "charlie", "delta", "echo", "foxtrot")

pie_chart(example, main = "resps", labels = ex_labs) +
  labs(title = "unfacetted example")
Run Code Online (Sandbox Code Playgroud)

无瑕疵的饼图憎恶

ex_labs2 <- c("alpha", "charlie", "foxtrot", "delta", "charlie", "echo")

pie_chart(example, main = "resps", labels = ex_labs2, condition = "cond") +
  labs(title = "facetted example")
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

  • 解决了@Reno.我更改了以下行`label_pos = sum(perc) - cumsum(perc)+ perc/2` (2认同)