函数传递data.frame和变量以构建公式

时间:2014-03-14 20:46:30

标签: r function dataframe formula vegan

我正在使用纯素包来做一些分析和绘图,比如这个

require(vegan)
data(varechem)
data(varespec)

rdam <- rda(varechem,scale=T)


scal=2
ef <- envfit(rdam ~ Cal.vul, data = varespec)
sf <- ordisurf(rdam ~ Cal.vul, data = varespec, plot = FALSE, scaling = scal)
plot(rdam, type="po",scaling = scal)
spe.sc <- scores(rdam, choices=1:2, display="sp",scaling = scal)
arrows(0, 0, spe.sc[, 1], spe.sc[, 2], length=0, lty=1, col="red")
ordilabel(rdam,dis="sp",cex=0.8,col="red",scaling = scal)
plot(ef)
plot(sf, col = "darkgreen", add = TRUE)

但是我必须重复相同的情节,只改变变量Cal.vul,所以我想做一个函数:

plot_spcSurface <- function(rdam,speFram, speName, scal=2 )
{
  ef <- envfit(rdam ~ speName, data = speFram)
  sf <- ordisurf(rdam ~ speName, data = speFram, plot = FALSE, scaling = scal)
  plot(rdam, type="po",scaling = scal)
  spe.sc <- scores(rdam, choices=1:2, display="sp",scaling = scal)
  arrows(0, 0, spe.sc[, 1], spe.sc[, 2], length=0, lty=1, col="red")
  ordilabel(rdam,dis="sp",cex=0.8,col="red",scaling = scal)
  plot(ef)
  plot(sf, col = "darkgreen", add = TRUE)

}  

plot_spcSurface(rdam,varespec,Cal.vul)

它给出了

objeto 'Cal.vul' not found 

如果我称之为

plot_spcSurface(rdam,varespec,varespec$Cal.vul)

它有效,但物种的名称标注不正确&#34; speName&#34;而不是&#34; Cal.vul&#34;而我无法从函数内部获取名称,这样做的正确方法是什么?

由于

2 个答案:

答案 0 :(得分:2)

你使这比实际需要的更复杂;弄乱公式并传递未评估的参数,如果不是问题,在你开始编写函数时会引起麻烦。

相反,请使用相应函数的默认版本,这些函数将排序对象和变量绘制为参数而不是公式。

这是一个版本:

plot_spcSurface <- function(ord, speFrame, speName, scal=2 ) {
  ef <- envfit(ord, speFrame[[speName]])
  sf <- ordisurf(ord, speFrame[[speName]], plot = FALSE, scaling = scal)
  plot(ord, type="po", scaling = scal)
  spe.sc <- scores(ord, choices=1:2, display="sp", scaling = scal)
  arrows(0, 0, spe.sc[, 1], spe.sc[, 2], length=0, lty=1, col="red")
  ordilabel(ord, dis="sp", cex=0.8, col="red", scaling = scal)
  plot(ef, labels = speName)
  plot(sf, col = "darkgreen", add = TRUE)
  invisible()
}

plot_spcSurface(rdam, varespec, "Cal.vul")

## or in the development version of vegan >= 2.1-41
plot_spcSurface(rdam, varespec, "Callvulg")

现在唯一的问题是由于我没有考虑从envfit()返回的内部对象上没有存储标签的情况,上面的函数没有正确地标记箭头。 它应该,但有一个我在plot.envfit() 中没有考虑的角落案例,我现在将对R-forge 进行修复。 这已在R-forge上的r2862中修复。(请注意,在该版本中,Jari更改了物种代码,因此您现在需要"Callvulg"而不是"cal.vulg"。)

答案 1 :(得分:1)

试试这个:

plot_spcSurface <- function(rdam,speFram, speName, scal=2 )
{
  form <- as.formula(paste("rdam~",speName))
  ef <- envfit(form, data = speFram)
  sf <- ordisurf(form, data = speFram, plot = FALSE, scaling = scal)
  plot(rdam, type="po",scaling = scal)
  spe.sc <- scores(rdam, choices=1:2, display="sp",scaling = scal)
  arrows(0, 0, spe.sc[, 1], spe.sc[, 2], length=0, lty=1, col="red")
  ordilabel(rdam,dis="sp",cex=0.8,col="red",scaling = scal)
  plot(ef)
  plot(sf, col = "darkgreen", add = TRUE)

}  

plot_spcSurface(rdam,varespec,"Cal.vul")

这会将预测变量的名称作为字符串传递,并在内部构建公式。