ggplot2:仅显示一个组中的文本标签

时间:2016-11-17 15:26:05

标签: r ggplot2

我的设置:

我有一群篮球运动员和他们的统计数据。

library(tidyverse)

df <- tibble(
  season = c(2010, 2011, 2012, 2013, 2014,
             2010, 2011, 2012, 2013, 2014),
  player = c("player_a", "player_a", "player_a", "player_a", "player_a",
             "league_avg", "league_avg", "league_avg", "league_avg", "league_avg"),
  fg_perc = c(.4912, .6083, .3095, .5525, .4289,
              .4825, .4836, .4819, .4860, .4848),
  points_game = c(20, 18, 15, 19, 18,
                  12, 12, 13, 11, 12)
)

我已经为player_a和league_avg显示了某个列(fg_perc)作为geom_line()。我还将它包装在自定义函数中,因为我将使用相同的方法进行其他统计。

make_chart <- function(target_column) {
  df %>% 
    ggplot(aes_string("season", target_column, label = target_column)) + 
    geom_line(aes(color = player), size = 1.33)
}

make_chart("fg_perc")

我的问题:

我想将fg_perc值仅显示为player_a数据的百分比。我无法弄清楚如何在不消除传奇的情况下做到这一点(当我传播()league_avg时)。我正在寻找一种能够按原样保留非百分比数字的解决方案,并以类似的方式显示它们(例如,仅限于player_a的points_game)。输出看起来像这样(请原谅MS Paint):

enter image description here

谢谢!

3 个答案:

答案 0 :(得分:4)

检查一下: 您可以使用geel_text中的ifelse设置条件:

  • 如果玩家==感兴趣的玩家,标签将是%值

  • 否则,标签将为空&#34; &#34;

你可以随心所欲,也可以是多个玩家。

df %>% 
        ggplot(aes(season,fg_perc))+
        geom_line(aes(color = player), size = 1.33)+
        geom_text(aes(label=ifelse(player=="player_a",paste0(100*fg_perc,"%")," ")))

enter image description here

修改

如果要将代码包装在函数中,可以尝试使用以下内容,在 geom_text 中使用 aes_string ,以便能够将列名称作为一个字符串。

如果所有目标列都是百分比:

  • 你可以在函数中预先将列乘以100(或在传递df之前进行mutate)

    make_chart <- function(target_column) {
    
        df[,target_column] <- 100*df[,target_column]
    
        df %>% 
                ggplot(aes_string("season", target_column)) + 
                geom_line(aes(color = player), size = 1.33) +
                geom_text(data=filter(df,player=="player_a"),
                          aes_string(label=target_column))+
                # a work around to add the % sign
                geom_text(data=filter(df,player=="player_a"),
                          aes(label="%"),
                          hjust=-1.5) }
    

enter image description here

答案 1 :(得分:3)

这里的诀窍是使用geom_label几何体和调整label美学:

df %>% ggplot(aes(season, fg_perc, color = player)) + 
    geom_line() + 
    geom_label(aes(label = ifelse(player == 'league_avg', NA, fg_perc)))

现在,只有label我们将fg_perc值设置为NA,如果playerleague_avg,则会从图中省略它们。 / p>

enter image description here

答案 2 :(得分:1)

如果您想在没有硬编码的情况下使用make_chart功能,您将需要使用非标准评估(nse)。许多tidyverse函数都有nse版本,在函数名后面用_表示。如果您以编程方式使用这些版本,则可以使用这些版本。

以下是使用aesfilteraes_filter_的nse版本的粗略示例。使用nse构建函数要比我在这里完成的功能要多得多。我建议你阅读dplyr vignette on nse了解更多信息。

我只是使用filter_而不是ifelse复制了@OmaymaS提供的解决方案。我还冒昧地向您的函数添加了数据参数.data以及player_highlight参数。 .data允许您的功能可管理,player_highight可让您选择要突出显示的播放器(因为它们可能不止一个)。您很可能希望扩展功能,并且应该这样做!

library(tidyverse)

df <- data_frame(
  season = c(2010, 2011, 2012, 2013, 2014,
             2010, 2011, 2012, 2013, 2014),
  player = c("player_a", "player_a", "player_a", "player_a", "player_a",
             "league_avg", "league_avg", "league_avg", "league_avg", "league_avg"),
  fg_perc = c(.4912, .6083, .3095, .5525, .4289,
              .4825, .4836, .4819, .4860, .4848),
  points_game = c(20, 18, 15, 19, 18,
                  12, 12, 13, 11, 12)
)


make_chart <- function(.data, target_column, player_highlight) {
    ggplot(.data, aes_(x = ~season, y = as.name(target_column))) + 
    geom_line(aes_(color = ~player), size = 1.33) +
    geom_text(data = filter_(.data, ~ player == player_highlight), aes_(label = as.name(target_column)))
}

make_chart(df,"fg_perc","player_a")

df %>% 
  make_chart("fg_perc","player_a")