我大致有这个功能:
plot_pca_models <- function(models, id) {
library(lattice)
splom(models, groups=id)
}
我称之为:
plot_pca_models(data.pca, log$id)
导致此错误:
Error in eval(expr, envir, enclos) : object 'id' not found
当我在没有包装功能的情况下调用它时:
splom(data.pca, groups=log$id)
它引发了这个错误:
Error in log$id : object of type 'special' is not subsettable
但是当我这样做时:
id <- log$id
splom(models, groups=id)
它的行为符合预期。
任何人都可以解释为什么它的行为如此以及如何纠正它?感谢。
顺便说一句: 我在这里也知道类似的问题,例如:
但他们都没有帮助我。
修改: 根据要求,有完整的“plot_pca_models”功能:
plot_pca_models <- function(data, id, sel=c(1:4), comp=1) {
# 'data' ... princomp objects
# 'id' ... list of samples id (classes)
# 'sel' ... list of models to compare
# 'comp' ... which pca component to compare
library(lattice)
models <- c()
models.size <- 1:length(data)
for(model in models.size) {
models <- c(models, list(data[[model]]$scores[,comp]))
}
names(models) <- 1:length(data)
models <- do.call(cbind, models[sel])
splom(models, groups=id)
}
EDIT2 : 我设法使问题重现。
require(lattice)
my.data <- data.frame(pca1 = rnorm(100), pca2 = rnorm(100), pca3 = rnorm(100))
my.id <- data.frame(id = sample(letters[1:4], 100, replace = TRUE))
plot_pca_models2 <- function(x, ajdi) {
splom(x, group = ajdi)
}
plot_pca_models2(x = my.data, ajdi = my.id$id)
产生与上述相同的错误。
答案 0 :(得分:2)
log
是基础R中的一个函数。良好的做法是不在函数之后命名对象......它可能会造成混淆。在一个干净的R会话中键入log$test
,您将看到发生了什么:
object of type 'special' is not subsettable
答案 1 :(得分:2)
问题是splom
以非标准方式评估其groups
参数。快速解决方法是重写函数,以便使用适当的语法构造调用:
f <- function(data, id)
eval(substitute(splom(data, groups=.id), list(.id=id)))
# test it
ir <- iris[-5]
sp <- iris[, 5]
f(ir, sp)
答案 2 :(得分:2)
以下是洪爱答案的修改。首先,我建议在主数据框中包含id,即
my.data <- data.frame(pca1 = rnorm(100), pca2 = rnorm(100), pca3 = rnorm(100), id = sample(letters[1:4], 100, replace = TRUE))
..然后
plot_pca_models2 <- function(x, ajdi) {
Call <- bquote(splom(x, group = x[[.(ajdi)]]))
eval(Call)
}
plot_pca_models2(x = my.data, ajdi = "id")
混淆的原因是格子::: splom.formula中的以下行:
groups <- eval(substitute(groups), data, environment(formula))
......唯一的一点就是能够指定没有引号的组,即
# instead of
splom(DATA, groups="ID")
# you can now be much shorter, thanks to eval and substitute:
splom(DATA, groups=ID)
但是,当然,这使得使用splom(和其他函数,例如使用“非标准评估”的替代品)更难以在其他函数中使用,并且违背了在R的其余部分“大部分”遵循的哲学。 / p>