График создан вне функции, а не внутри - PullRequest
0 голосов
/ 06 августа 2020

Немного новичок в R, и я думаю, что могу неправильно понять, как работают функции в R. Когда я пишу этот код:

past_annual <- past_day %>% 
group_by(year) %>% 
summarize(annual_avg = mean(runoff_daily, na.rm = TRUE))

future_annual <- future_day %>% 
    group_by(year) %>% 
    summarize(annual_avg_45 = mean(runoff_daily_45, na.rm = TRUE),
              annual_avg_85 = mean(runoff_daily_85, na.rm = TRUE))

ggplot() +
    geom_line(data = past_annual, aes(x = year, y = annual_avg),
              color = "gray60") +
    geom_line(data = future_annual, aes(x = year, y = annual_avg_45),
              color = "turquoise4") +
    geom_line(data = future_annual, aes(x = year, y = annual_avg_85),
              color = "darkgoldenrod3") +
    theme_minimal()

Он создает график runoff_graph

Но когда я пытаюсь записать его в функцию, он создает пустой график.

plot_annual = function(.y, .x, .z) {
  
  past_annual <- past_day %>% 
    group_by(year) %>% 
    summarize(annual_avg = mean(.y, na.rm = TRUE))
  
   future_annual <- future_day %>% 
    group_by(year) %>% 
    summarize(annual_avg_45 = mean(.x, na.rm = TRUE),
              annual_avg_85 = mean(.z, na.rm = TRUE))
  
  annual_graph <- ggplot() +
    geom_line(data = past_annual, 
              aes(x = year, y = annual_avg),
              color = "gray60") +
    geom_line(data = future_annual, 
              aes(x = year, y = annual_avg_45),
              color = "turquoise4") +
    geom_line(data = future_annual, 
              aes(x = year, y = annual_avg_85),
              color = "darkgoldenrod3") +
    theme_minimal()
  
  return(annual_graph)
}

plot_annual("runoff_daily", "runoff_daily_45", "runoff_daily_85")

function_graph

Что мне здесь не хватает? Я скопировал код прямо из функции и заменил переменные на то, что хочу, поэтому я очень запутался. Кроме того, это мой первый пост о переполнении стека, так что извиняюсь, если мне не хватает важной информации, чтобы ответить на мой вопрос.

1 Ответ

0 голосов
/ 06 августа 2020

Думаю, проблема больше в том, как вы используете аргументы функции. Рассмотрим следующее:

iris %>% 
  group_by(Species) %>% 
  summarize(avg_1 = mean(Sepal.Length),
            avg_2 = mean(Sepal.Width))

  Species    avg_1 avg_2
  <fct>      <dbl> <dbl>
1 setosa      5.01  3.43
2 versicolor  5.94  2.77
3 virginica   6.59  2.97

Обратите внимание, что Sepal.Length и Sepal.Width не заключены в двойные кавычки. Это основано на особенностях работы dplyr и tidyverse в целом.

Теперь попробуйте следующее:

iris %>% 
  group_by(Species) %>% 
  summarize(avg_1 = mean("Sepal.Length"),
            avg_2 = mean("Sepal.Width"))

# A tibble: 3 x 3
  Species    avg_1 avg_2
  <fct>      <dbl> <dbl>
1 setosa        NA    NA
2 versicolor    NA    NA
3 virginica     NA    NA

Warning messages:
1: In mean.default("Sepal.Length") :
  argument is not numeric or logical: returning NA
2: In mean.default("Sepal.Length") :
  argument is not numeric or logical: returning NA
3: In mean.default("Sepal.Length") :
  argument is not numeric or logical: returning NA
4: In mean.default("Sepal.Width") :
  argument is not numeric or logical: returning NA
5: In mean.default("Sepal.Width") :
  argument is not numeric or logical: returning NA
6: In mean.default("Sepal.Width") :
  argument is not numeric or logical: returning NA

Не работает. По сути, это то, что делает ваша функция.

f <- function(.x, .y) {
  iris %>% 
    group_by(Species) %>% 
    summarize(avg_1 = mean(.x),
              avg_2 = mean(.y))
}

f("Sepal.Length", "Sepal.Width")

# A tibble: 3 x 3
  Species    avg_1 avg_2
  <fct>      <dbl> <dbl>
1 setosa        NA    NA
2 versicolor    NA    NA
3 virginica     NA    NA

Warning messages:
1: In mean.default("Sepal.Length") :
  argument is not numeric or logical: returning NA
2: In mean.default("Sepal.Length") :
  argument is not numeric or logical: returning NA
3: In mean.default("Sepal.Length") :
  argument is not numeric or logical: returning NA
4: In mean.default("Sepal.Width") :
  argument is not numeric or logical: returning NA
5: In mean.default("Sepal.Width") :
  argument is not numeric or logical: returning NA
6: In mean.default("Sepal.Width") :
  argument is not numeric or logical: returning NA

Обойти это на самом деле довольно просто, но немного сложнее. Вы можете прочитать об этом здесь, что объяснит это намного лучше, чем я: https://adv-r.hadley.nz/quasiquotation.html.

Но пока вот что должно работать. Я не могу воспроизвести ваш пример, но вы можете применить ту же концепцию.

f <- function(.x, .y) {
  .x <- rlang::ensym(.x)
  .y <- rlang::ensym(.y)
  
  iris %>% 
    group_by(Species) %>% 
    summarize(avg_1 = mean(!!.x),
              avg_2 = mean(!!.y))
}

f("Sepal.Length", "Sepal.Width")

# A tibble: 3 x 3
  Species    avg_1 avg_2
  <fct>      <dbl> <dbl>
1 setosa      5.01  3.43
2 versicolor  5.94  2.77
3 virginica   6.59  2.97

Другой вариант - использовать местоимение .data, которое подразумевается в dplyr.

f <- function(.x, .y) {
  iris %>% 
    group_by(Species) %>% 
    summarize(avg_1 = mean(.data[[.x]]),
              avg_2 = mean(.data[[.y]]))
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...