代码之家  ›  专栏  ›  技术社区  ›  J.Sabree

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

  •  1
  • J.Sabree  · 技术社区  · 4 年前

    我试图在一个函数中使用双花括号来绘制timeseries绘图,尽管读到了这篇文章,我还是遇到了麻烦 overview 关于双曲括号的工作原理。

    在该函数中,用户指定他们希望绘图关注的时间段(周或月)。如果用户选择“月”,则绘图的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")
    

    可笑的错误输出:

    enter image description here

    2 回复  |  直到 4 年前
        1
  •  1
  •   Rui Barradas    4 年前

    双卷发大括号与 unquoted variables names .如果变量名称为字符串,请使用 aes_string ,另见 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")
    

    于2022年4月2日由 reprex package (v2.0.1)

        2
  •  0
  •   jpiversen    4 年前

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

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

    # Defining an env-variable
    cyl <- 1000
    
    # Referring to a data-variable
    dplyr::summarise(mtcars, mean(cyl))
    #>   mean(cyl)
    #> 1    6.1875
    

    于2022年4月2日由 reprex package (v2.0.1)

    如何修复你的函数

    有更简单的方法来修复你的函数,而不用使用 {{}} ,但如果你想看看如何使用 {{}} 我在这里举了一个例子。

    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)
    

    于2022年4月2日由 reprex包装 (v2.0.1)

    我更改了以下内容:

    • 因为你想把一个字符串粘贴到 time_period 时间段 是一个不带引号的变量,需要使用 rlang::as_name(enquo(time_period)) .
    • 自从 time_period_score 是一个字符串,你需要提供给 aes() 一串。自从 时间段 aes_string() ,所以我用 .data 代名词 .data[[time_period_score]] .

    你可以找到更多关于 {{}} here .

    推荐文章