如何使用列中的值绘制雷达图?

How can I plot a radar plot with values from columns?

我想绘制一个雷达图,如下所示,用行的唯一值替换 Var 符号,并按列分组(右侧是我想要完成的,忽略蓝色区域) :

我遵循了数据帧结构:

# install.packages("fmsb")
library(fmsb)
ser <- rep(c(4.5, 3.0, 4.0, 1.0, 1.0, 3.5, 4.5, 3.0, 3.0, 4.0, 
               3.0, 4.5, 4.5, 4.0, 3.0, 1.5, 1.5, 2.0, 2.0,
               3.5, 4.5, 3.5, 3.0, 3.0, 4.5, 4.5, 2.5, 4.5),100)

avg <- rep(c(4.5, 3.5, 4.0, 1.0, 4.0, 3.5, 4.5, 4.0, 1.0, 4.0, 
               3.0, 4.5, 4.0, 3.0, 1.5, 1.5, 2.0, 2.0,
               3.5, 4.5, 3.5, 3.5, 4.0, 3.0, 4.0, 4.0, 2.5, 4.5),100)

df <- data.frame(ser, avg)

左图示例代码here.

悬赏注意事项:也接受与 ggplot 类似的解决方案。

为了使用唯一值而不是 fmsb::radarchart 中的“Var”名称,我们需要将数据重新格式化为一个数据框,该数据框将这些值作为列名,并将每组的相应值作为行,这可以完成,例如使用 tidyverse:

library(dplyr)
library(tidyr)

# prepare data for radarplot format
df1 <- df %>%
  tidyr::pivot_longer(c(ser, avg)) %>%
  group_by(name, value) %>% 
  #whatevery summary statistic required
  dplyr::summarise(target_stat = n()/nrow(df)) %>%
  tidyr::pivot_wider(id_cols = "name", 
                     names_from = "value", 
                     values_from = "target_stat") %>%
  # ensure numeric values of column names are in correct order
  dplyr::select(order(colnames(.))) %>%
  dplyr::ungroup()

# keep group labels in correct order for later
gr_names <- df1$name

#remove names from plot data
df1 <- df1 %>%
  dplyr::select(-name)

此外,如果我们想控制轴范围(此处:所有变量的范围相同)。正如在另一个答案中指出的那样,如果每个轴的独立 auto-scaling 是可以接受的,则 radarchart(..., maxmin = FALSE) 不需要此步骤。

# specify max & min rows
df_min_max <- data.frame(
  rbind(
    rep(max(df1), ncol(df1)),
    rep(0, ncol(df1)))
)

#combine ranges and data
colnames(df_min_max) <-  colnames(df1)
df_plot <- bind_rows(df_min_max, df1)  

df_plot

#     1  1.5    2  2.5    3  3.5    4  4.5
#1 3600 3600 3600 3600 3600 3600 3600 3600
#2    0    0    0    0    0    0    0    0
#3  200  300  400  250 2100 1050 1200 3600
#4  200  300  400  250  900 1750 3200 2250

这可以类似于问题中链接的示例代码使用。

## specify colors
col_points <- c(rgb(1, 0, 0), rgb(0, 0, 1))
col_areas <- c(rgb(1, 0, 0, 0.2), rgb(0, 0, 1, 0.2))


df_plot %>% 
  radarchart(
    pcol = col_points,
    pfcol = col_areas)

legend("topright",
       legend = gr_names,
       bty = "n", pch = 20, col = col_areas,
       pt.cex = 2)

您还可以使用 ggradar 包中的 ggradar 函数。

library(tidyverse)
library(ggradar)

df = tibble(
  ser = rep(c(4.5, 3.0, 4.0, 1.0, 1.0, 3.5, 4.5, 3.0, 3.0, 4.0, 
             3.0, 4.5, 4.5, 4.0, 3.0, 1.5, 1.5, 2.0, 2.0,
             3.5, 4.5, 3.5, 3.0, 3.0, 4.5, 4.5, 2.5, 4.5),100),
  avg = rep(c(4.5, 3.5, 4.0, 1.0, 4.0, 3.5, 4.5, 4.0, 1.0, 4.0, 
             3.0, 4.5, 4.0, 3.0, 1.5, 1.5, 2.0, 2.0,
             3.5, 4.5, 3.5, 3.5, 4.0, 3.0, 4.0, 4.0, 2.5, 4.5),100))

df %>% pivot_longer(everything()) %>% 
  group_by(name, value) %>% 
  summarise(n = n()/1000) %>% 
  pivot_wider(names_from = value, values_from = n) %>% 
  ggradar(grid.label.size = 4, axis.label.size = 4) 

上述解决方案的注释(还不能发表评论):

  • 您可以在使用 maxmin=FALSE
  • 调用 radarchart 时跳过最大和最小行
  • radarchart 绘图 counter-clockwise 这可能会使具有可排名名称的变量混淆(如您的情况)。如果需要,像这样反转任何 data.frame 的列顺序:df_reverse <- rev(df).