r - 图表在函数之外创建,而不是在函数内部创建
问题描述
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")
我在这里想念什么?我直接从函数内部复制了代码并将变量替换为我想要的变量,所以我很困惑。另外,这是我的第一个堆栈溢出帖子,如果我错过了一些关键信息来回答我的问题,请道歉。
解决方案
我认为问题更多在于您如何使用函数参数。考虑以下:
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]]))
}