parse函数解析字符串为表达式;eval函数执行表达式输出结果;parse函数和eval函数在自定义函数中常常非常有用
library(ggplot2)
rm(list = ls())
例子1
b为字符换:“character”
b <- "
for (i in 1:5) {
print(i)
}
"
class(b)
# [1] "character"
parse函数将b转化为表达式:“expression”
parsed_b <- parse(text = b)
parsed_b
# expression(for (i in 1:5) {
# print(i)
# })
class(parsed_b)
# [1] "expression"
eval函数执行表达式
eval(parsed_b)
# [1] 1
# [1] 2
# [1] 3
# [1] 4
# [1] 5
例子2
mtcars为R自带的有关汽车的数据集
class(mtcars)
# [1] "data.frame"
class(parse(text = "mtcars"))
# [1] "expression"
class(eval(parse(text = "mtcars")))
# [1] "data.frame"
head(eval(parse(text = "mtcars")))
# mpg cyl disp hp drat wt qsec vs am gear
# Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4
# Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4
# Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4
# Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3
# Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3
# Valiant 18.1 6 225 105 2.76 3.460 20.22 1 0 3
# carb
# Mazda RX4 4
# Mazda RX4 Wag 4
# Datsun 710 1
# Hornet 4 Drive 1
# Hornet Sportabout 2
# Valiant 1
例子3:回归函数lm中
使用mtcars数据集,以wt为因变量,欲分别建立mpg、cyl、disp、hp、drat与wt的回归模型
以wt与mpg的回归模型为例,可以直接这样写
lm(wt ~ mpg, data = mtcars)
#
# Call:
# lm(formula = wt ~ mpg, data = mtcars)
#
# Coefficients:
# (Intercept) mpg
# 6.0473 -0.1409
如果建模过程语句较多,而不同模型仅仅是自变量发生了变化,那么编写函数可以简化过程。
编写函数时该如何指明自变量那?
以下函数编写方式行不通,"mpg"或mpg无法正确识别
# lm_func <- function(var) {
# lm(wt ~ var, data = mtcars)
# }
#
# lm_func(var = mpg)
# lm_func(var = "mpg")
查阅帮助可知,lm函数的第一个参数为formula
# lm(formula = , data = )
使用parse函数和eval函数将字符串形式的"wt ~ mpg"转换为formula,再带入lm函数后可以正确运行
class(eval(parse(text = "wt ~ mpg")))
# [1] "formula"
lm(eval(parse(text = "wt ~ mpg")), data = mtcars)
#
# Call:
# lm(formula = eval(parse(text = "wt ~ mpg")), data = mtcars)
#
# Coefficients:
# (Intercept) mpg
# 6.0473 -0.1409
根据上述信息,lm_func函数可编写为
lm_func <- function(var) {
lm(eval(parse(text = paste0("wt ~ ", var))), data = mtcars)
}
lm_func(var = "mpg") # 正确执行了
#
# Call:
# lm(formula = eval(parse(text = paste0("wt ~ ", var))), data = mtcars)
#
# Coefficients:
# (Intercept) mpg
# 6.0473 -0.1409
除了使用parse函数和eval函数,另一种方法是使用formula函数将字符串"wt ~ mpg"直接转换为formula
class(formula("wt ~ mpg"))
# [1] "formula"
lm(formula("wt ~ mpg"), data = mtcars)
#
# Call:
# lm(formula = formula("wt ~ mpg"), data = mtcars)
#
# Coefficients:
# (Intercept) mpg
# 6.0473 -0.1409
使用formula函数,lm_func可编写为
lm_func <- function(var) {
lm(formula(paste0("wt ~ ", var)), data = mtcars)
}
lm_func(var = "mpg") # 正确执行了
#
# Call:
# lm(formula = formula(paste0("wt ~ ", var)), data = mtcars)
#
# Coefficients:
# (Intercept) mpg
# 6.0473 -0.1409
例子4:绘图函数ggplot中
使用mtcars数据集,以wt为因变量,欲分别绘制mpg、cyl、disp、hp、drat与wt的散点图
以wt与mpg的散点图为例,可以直接这样写
ggplot(data = mtcars, aes(x = mpg, y = wt)) +
geom_point() +
labs(x = "mpg", y = "wt") +
theme_bw()
这样编写绘图函数,结果表明行不通
# plot_func <- function(var) {
# ggplot(data = mtcars, aes(x = var, y = wt)) +
# geom_point() +
# labs(x = var, y = "wt") +
# theme_bw()
# }
#
# plot_func(var = mpg)
# plot_func(var = "mpg")
尝试使用eval函数和parse函数,结果表明这样可以正确运行
ggplot(data = mtcars, aes(x = eval(parse(text = "mpg")),
y = eval(parse(text = "wt")))) +
geom_point() +
labs(x = "mpg", y = "wt") +
theme_bw()
根据上述信息,plot_func函数可编写为
plot_func <- function(var) {
ggplot(data = mtcars, aes(x = eval(parse(text = var)),
y = eval(parse(text = "wt")))) +
geom_point() +
labs(x = var, y = "wt") +
theme_bw()
}
plot_func(var = "mpg") # 正确运行了
另一种方法:ggplot函数参数中,将aes改为aes_string可以正确处理字符串对象
ggplot(data = mtcars, aes_string(x = "mpg", y = "wt")) +
geom_point() +
labs(x = "mpg", y = "wt") +
theme_bw()
使用aes_string,绘图函数还可编写为
plot_func <- function(var) {
ggplot(data = mtcars, aes_string(x = var, y = "wt")) +
geom_point() +
labs(x = var, y = "wt") +
theme_bw()
}
plot_func(var = "mpg") # 正确运行了