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] 5mtcars为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使用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使用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") # 正确运行了