如何在 R 中使用带有 ggplot 和日期的双大括号?

How to use double curly brackets in R with ggplot and dates?

我试图在制作时间序列图的函数中使用双大括号,尽管阅读了这篇关于双大括号通常如何工作的,但我还是碰壁了。

在此功能中,用户指定他们希望绘图关注的时间段(周或月)。如果用户选择“月份”,则绘图的 X 轴应为 Month 日期,Y 轴应为 Month_score 列。

我以为我明白这是如何工作的,但我的情节没有显示任何数据:

library(dplyr)
library(ggplot2)
library(lubdridate)

#Sample data
test <- tibble(Week = seq(as.Date("2014/09/04"), by = "week", length.out = 8),
               Month = ymd(rep('2014-09-01', 4), rep('2014-10-01', 4)),
               Week_score = c(2, 3, 4, 6, 5, 7, 8, 9),
               Month_score = c(15, NA, NA, NA, 29, NA, NA, NA))

#My function
make_time_plot <- function(data, time_period = c("Week", "Month")) {

  time_period_score <- paste0(time_period, "_score")
  
  data %>%
    ggplot(aes(x = {{time_period}}, y = {{time_period_score}})) +
    geom_line()
}

#Proof that it doesn't work :-(
make_time_plot(data = test, time_period = "Month")

可笑的错误输出:

双花括号与 . With variables names as character strings, use aes_string, see also here 一起使用。

suppressPackageStartupMessages({
  library(dplyr)
  library(ggplot2)
  library(lubridate)
})

#Sample data
test <- tibble(Week = seq(as.Date("2014/09/04"), by = "week", length.out = 8),
               Month = ymd(rep('2014-09-01', 4), rep('2014-10-01', 4)),
               Week_score = c(2, 3, 4, 6, 5, 7, 8, 9),
               Month_score = c(15, NA, NA, NA, 29, NA, NA, NA))

#My function
make_time_plot <- function(data, time_period = c("Week", "Month")) {
  
  time_period <- match.arg(time_period)
  time_period_score <- paste0(time_period, "_score")
  
  data %>%
    ggplot(aes_string(x = time_period, y = time_period_score)) +
    geom_line()
}

#make_time_plot(data = test, time_period = "Month")
make_time_plot(data = test, time_period = "Week")

reprex package (v2.0.1)

于 2022-04-02 创建

这里发生了几件事。 {{}} 处理不带引号的变量,不能与字符串混合匹配。

例如:当你写mtcars %>% select(hp)时,你不需要写"hp"。这是由于“数据屏蔽”,一个使 R 理解 hpmtcars 中的变量而不是您环境中的变量的过程。使这段代码工作的不是这个过程:

# Defining an env-variable
cyl <- 1000

# Referring to a data-variable
dplyr::summarise(mtcars, mean(cyl))
#>   mean(cyl)
#> 1    6.1875

reprex package (v2.0.1)

于 2022-04-02 创建

如何修复您的功能

有更简单的方法来修复您的功能,无需使用 {{}},但如果您想了解如何使用 {{}} 来完成,我在此处提供了一个示例。

make_time_plot <- function(data, time_period) {
  
  time_period_score <- paste0(rlang::as_name(enquo(time_period)), "_score")
  
  data %>%
    ggplot(
      aes(
        x = {{time_period}},
        y = .data[[time_period_score]]
      )
    ) +
    geom_line()
}

make_time_plot(data = test, time_period = Week)

reprex package (v2.0.1)

于 2022-04-02 创建

我更改了以下内容:

  • 由于要将字符串粘贴到time_period,而time_period是一个不带引号的变量,因此需要使用rlang::as_name(enquo(time_period)).
  • 将其变成字符串
  • 由于 time_period_score 是一个字符串,您需要将其作为字符串提供给 aes()。由于 time_period 不是字符串,您不能使用 aes_string(),所以我使用 .data 代词和 .data[[time_period_score]]

您可以找到有关 {{}} here 的更多信息。