R中的圆形堆叠条形图-美学长度必须为1或与数据相同(26) [英] Circular stacked barplot in R - Aesthetics must be either length 1 or the same as the data (26)

查看:79
本文介绍了R中的圆形堆叠条形图-美学长度必须为1或与数据相同(26)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个此处所述的圆形堆叠条形图(

I am trying to create a circular stacked barplot as mentioned here (https://www.r-graph-gallery.com/299-circular-stacked-barplot.html). And I get the following error when when I get to the step of making the plot (in bold below):

Error: Aesthetics must be either length 1 or the same as the data (26): hjust Run rlang::last_error() to see where the error occurred. In addition: Warning message: Removed 208 rows containing missing values (position_stack).

This is what my data looks like (with 5 columns and 70 rows):

Individual; group; value1; value2; value3; value4

Here are my codes:

Transform data in a tidy format (long format)

data <- data %>% gather(key = "observation", value="value", -c(1,2)) 

Make the plot

p <- ggplot(data) +

  geom_bar(aes(x=as.factor(id), y=value, fill=observation), stat="identity", alpha=0.5) +
  scale_fill_viridis(discrete=TRUE) + 

  geom_segment(data=grid_data, aes(x = end, y = 0, xend = start, yend = 0), colour = "grey", alpha=1, size=0.3 , inherit.aes = FALSE ) +
  geom_segment(data=grid_data, aes(x = end, y = 2, xend = start, yend = 2), colour = "grey", alpha=1, size=0.3 , inherit.aes = FALSE ) +
  geom_segment(data=grid_data, aes(x = end, y = 4, xend = start, yend = 4), colour = "grey", alpha=1, size=0.3 , inherit.aes = FALSE ) +
  geom_segment(data=grid_data, aes(x = end, y = 6, xend = start, yend = 6), colour = "grey", alpha=1, size=0.3 , inherit.aes = FALSE ) +
  geom_segment(data=grid_data, aes(x = end, y = 8, xend = start, yend = 8), colour = "grey", alpha=1, size=0.3 , inherit.aes = FALSE ) +

  ggplot2::annotate("text", x = rep(max(data$id),5), y = c(0, 2, 4, 6, 8), label = c("0", "2", "4", "6", "8") , color="grey", size=6 , angle=0, fontface="bold", hjust=1) +

  ylim(-150,max(label_data$tot, na.rm=T)) +
  theme_minimal() +
  theme(
    legend.position = "none",
    axis.text = element_blank(),
    axis.title = element_blank(),
    panel.grid = element_blank(),
    plot.margin = unit(rep(-1,4), "cm") 
  ) +
  coord_polar() +  

 geom_text(data=label_data, aes(x=id, y=tot+10, label=individual, hjust=hjust), color="black", fontface="bold",alpha=0.6, size=5, angle= label_data$angle, inherit.aes = FALSE ) +

 geom_segment(data=base_data, aes(x = start, y = -5, xend = end, yend = -5), colour = "black", alpha=0.8, size=0.6 , inherit.aes = FALSE )  +

  geom_text(data=base_data, aes(x = title, y = -18, label=group), hjust=c(1,1,0,0), colour = "black", alpha=0.8, size=4, fontface="bold", inherit.aes = FALSE) 

 **ggsave(p, file="output1.png", width=10, height=10)**

I would appreciate any help with this.

Thanks!!

individual group value1 value2 value3 value4

Biomarker1 Group1 0 1 2 2 Biomarker2 Group2 0 1 0 2 Biomarker3 Group2 0 1 0 1 Biomarker4 Group3 1 2 1 0 Biomarker5 Group4 0 2 4 1 Biomarker6 Group4 0 1 0 1 Biomarker7 Group4 0 1 0 1 Biomarker8 Group5 0 1 0 1 Biomarker9 Group6 0 1 1 1 Biomarker10 Group6 0 2 1 1

解决方案

This is the modified code from the linked post to produce a circular barplot with angled group labels in the centre.

library(ggplot2)
library(viridis)
library(tidyverse)

# Create dataset
data <- data.frame(
  individual=paste( "Mister ", seq(1,60), sep=""),
  group=c( rep('Group A', 10), rep('Group B', 30), rep('Group C', 14), rep('Group D', 6)) ,
  value=sample( seq(10,100), 60, replace=T), stringsAsFactors = TRUE)

# Set a number of 'empty bar' to add at the end of each group
empty_bar <- 3
to_add <- data.frame( matrix(NA, empty_bar*nlevels(data$group), ncol(data)) )
colnames(to_add) <- colnames(data)
to_add$group <- rep(levels(data$group), each=empty_bar)
data <- rbind(data, to_add)
data <- data %>% arrange(group)
data$id <- seq(1, nrow(data))

# Get the name and the y position of each label
label_data <- data
number_of_bar <- nrow(label_data)
angle <- 90 - 360 * (label_data$id-0.5) /number_of_bar 
label_data$hjust <- ifelse( angle < -90, 1, 0)
label_data$angle <- ifelse(angle < -90, angle+180, angle)

# prepare a data frame for base lines
base_data <- data %>% 
  group_by(group) %>% 
  summarize(start=min(id), end=max(id) - empty_bar) %>% 
  rowwise() %>% 
  mutate(title=mean(c(start, end)))


This is the additional code to create the angles for the group labels

angle <- 90 - 360 * (base_data$title-0.5)/number_of_bar  
base_data$angle <- ifelse(angle < -90, angle+180, angle)


# prepare a data frame for grid (scales)
grid_data <- base_data
grid_data$end <- grid_data$end[ c( nrow(grid_data), 1:nrow(grid_data)-1)] + 1
grid_data$start <- grid_data$start - 1
grid_data <- grid_data[-1,]

# Make the plot
ggplot(data, aes(x=as.factor(id), y=value, fill=group)) +       # Note that id is a factor. If x is numeric, there is some space between the first bar

  geom_bar(aes(x=as.factor(id), y=value, fill=group), stat="identity", alpha=0.5) +

# Add a val=100/75/50/25 lines. I do it at the beginning to make sur barplots are OVER it.
  geom_segment(data=grid_data, aes(x = end, y = 80, xend = start, yend = 80), colour = "grey", alpha=1, size=0.3 , inherit.aes = FALSE ) +
  geom_segment(data=grid_data, aes(x = end, y = 60, xend = start, yend = 60), colour = "grey", alpha=1, size=0.3 , inherit.aes = FALSE ) +
  geom_segment(data=grid_data, aes(x = end, y = 40, xend = start, yend = 40), colour = "grey", alpha=1, size=0.3 , inherit.aes = FALSE ) +
  geom_segment(data=grid_data, aes(x = end, y = 20, xend = start, yend = 20), colour = "grey", alpha=1, size=0.3 , inherit.aes = FALSE ) +

  # Add text showing the value of each 100/75/50/25 lines
  annotate("text", x = rep(max(data$id),4), y = c(20, 40, 60, 80), label = c("20", "40", "60", "80") , color="grey", size=3 , angle=0, fontface="bold", hjust=1) +

  geom_bar(aes(x=as.factor(id), y=value, fill=group), stat="identity", alpha=0.5) +
  ylim(-50,120) +
  theme_minimal() +
  theme(
    legend.position = "none",
    axis.text = element_blank(),
    axis.title = element_blank(),
    panel.grid = element_blank(),
#    plot.margin = unit(rep(-1,4), "cm") 
  ) +

  coord_polar() + 
  geom_text(data=label_data, aes(x=id, y=value+10, label=individual, hjust=hjust), color="black", fontface="bold",alpha=0.6, size=2.5, angle= label_data$angle, inherit.aes = FALSE ) +

# Add base line information
geom_segment(data=base_data, aes(x = start, y = -1, xend = end, yend = -1), colour = "black", alpha=0.6, size=0.8, inherit.aes = F ) +


And here we utilize the angle:

  geom_text(data=base_data, aes(x = title, y = -6, label=group, angle=angle), 
            hjust=c(1,1,0,0), colour = "black", alpha=0.7, size=2, fontface="bold", inherit.aes = FALSE)


这篇关于R中的圆形堆叠条形图-美学长度必须为1或与数据相同(26)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆