为什么重命名的函数不像 R 中的原始函数那样工作
why a renamed function doesn't work like the original function in R
我正在使用 match.call
将名为 factanal
的 BASE R 函数重命名为 efa
。但我想知道为什么只有在使用参数 x
的公式时,efa
才会引发错误:object 'n.obs' not found
但 factanal
可以正常工作?
注意: 当对 x
使用 data.frame
时,efa
工作正常。
efa <- function(x, factors, data = NULL, covmat = NULL, n.obs = NA,
subset, na.action, start = NULL, center = FALSE,
scores = c("none", "regression", "Bartlett"),
rotation = "varimax", control = NULL, ...)
{
fit <- factanal(x, factors, data = data, covmat, n.obs = n.obs,
subset, na.action, start = start,
scores = scores,
rotation = rotation, control = control, ...)
fit$call <- match.call(expand.dots = FALSE)
return(fit)
}
# Example of use:
v1 <- c(1,1,1,1,1,1,1,1,1,1,3,3,3,3,3,4,5,6)
v2 <- c(1,2,1,1,1,1,2,1,2,1,3,4,3,3,3,4,6,5)
v3 <- c(3,3,3,3,3,1,1,1,1,1,1,1,1,1,1,5,4,6)
factanal(~v1+v2+v3, factors = 1, data = data.frame(v1, v2, v3)) # Works fine
efa(~v1+v2+v3, factors = 1, data = data.frame(v1, v2, v3)) # Error: object 'n.obs' not found
efa(data.frame(v1, v2, v3), factors = 1) # Works fine
我认为更常见的做法是先捕获调用,封装任何参数,然后对其求值。像这样
efa <- function(x, factors, data = NULL, covmat = NULL, n.obs = NA,
subset, na.action, start = NULL, center = FALSE,
scores = c("none", "regression", "Bartlett"),
rotation = "varimax", control = NULL, ...)
{
cc <- match.call(expand.dots = FALSE)
cc[[1]] <- quote(factanal)
fit <- eval.parent(cc)
fit$call <- match.call(expand.dots = FALSE)
return(fit)
}
我们可以用
进行测试
efa(~v1+v2+v3, factors = 1, data = data.frame(v1, v2, v3))
# Call:
# efa(x = ~v1 + v2 + v3, factors = 1, data = data.frame(v1, v2, v3))
#
# Uniquenesses:
# v1 v2 v3
# 0.005 0.114 0.739
#
# Loadings:
# Factor1
# v1 0.998
# v2 0.941
# v3 0.511
#
# Factor1
# SS loadings 2.143
# Proportion Var 0.714
#
# The degrees of freedom for the model is 0 and the fit was 0.0609
此函数无法正常工作的原因是,当您将值传递给 n.obs
时,它假定这是您的 data.frame 中包含您的值的变量的名称希望使用,它不会假定这是您当前环境中的变量。
我正在使用 match.call
将名为 factanal
的 BASE R 函数重命名为 efa
。但我想知道为什么只有在使用参数 x
的公式时,efa
才会引发错误:object 'n.obs' not found
但 factanal
可以正常工作?
注意: 当对 x
使用 data.frame
时,efa
工作正常。
efa <- function(x, factors, data = NULL, covmat = NULL, n.obs = NA,
subset, na.action, start = NULL, center = FALSE,
scores = c("none", "regression", "Bartlett"),
rotation = "varimax", control = NULL, ...)
{
fit <- factanal(x, factors, data = data, covmat, n.obs = n.obs,
subset, na.action, start = start,
scores = scores,
rotation = rotation, control = control, ...)
fit$call <- match.call(expand.dots = FALSE)
return(fit)
}
# Example of use:
v1 <- c(1,1,1,1,1,1,1,1,1,1,3,3,3,3,3,4,5,6)
v2 <- c(1,2,1,1,1,1,2,1,2,1,3,4,3,3,3,4,6,5)
v3 <- c(3,3,3,3,3,1,1,1,1,1,1,1,1,1,1,5,4,6)
factanal(~v1+v2+v3, factors = 1, data = data.frame(v1, v2, v3)) # Works fine
efa(~v1+v2+v3, factors = 1, data = data.frame(v1, v2, v3)) # Error: object 'n.obs' not found
efa(data.frame(v1, v2, v3), factors = 1) # Works fine
我认为更常见的做法是先捕获调用,封装任何参数,然后对其求值。像这样
efa <- function(x, factors, data = NULL, covmat = NULL, n.obs = NA,
subset, na.action, start = NULL, center = FALSE,
scores = c("none", "regression", "Bartlett"),
rotation = "varimax", control = NULL, ...)
{
cc <- match.call(expand.dots = FALSE)
cc[[1]] <- quote(factanal)
fit <- eval.parent(cc)
fit$call <- match.call(expand.dots = FALSE)
return(fit)
}
我们可以用
进行测试efa(~v1+v2+v3, factors = 1, data = data.frame(v1, v2, v3))
# Call:
# efa(x = ~v1 + v2 + v3, factors = 1, data = data.frame(v1, v2, v3))
#
# Uniquenesses:
# v1 v2 v3
# 0.005 0.114 0.739
#
# Loadings:
# Factor1
# v1 0.998
# v2 0.941
# v3 0.511
#
# Factor1
# SS loadings 2.143
# Proportion Var 0.714
#
# The degrees of freedom for the model is 0 and the fit was 0.0609
此函数无法正常工作的原因是,当您将值传递给 n.obs
时,它假定这是您的 data.frame 中包含您的值的变量的名称希望使用,它不会假定这是您当前环境中的变量。