该包data.table具有一些特殊的语法,需要使用表达式作为i和j参数.
这对于一个接受并将参数传递给数据表的写函数有一些影响,正如常见问题解答第1.16节中所解释的那样.
但我无法弄清楚如何采取这一额外的水平.
这是一个例子.假设我想编写一个包装函数foo(),它对我的数据进行特定的汇总,然后是第二个plotfoo()调用foo()并绘制结果的包装器:
library(data.table)
foo <- function(data, by){
by <- substitute(by)
data[, .N, by=list(eval(by))]
}
DT <- data.table(mtcars)
foo(DT, gear)
Run Code Online (Sandbox Code Playgroud)
好的,这是有效的,因为我得到了我的表格结果:
by N
1: 4 12
2: 3 15
3: 5 5
Run Code Online (Sandbox Code Playgroud)
现在,我在写作的时候尝试的plotfoo()却是一样但是我悲惨地失败了:
plotfoo <- function(data, by){
by <- substitute(by)
foo(data, eval(by))
}
plotfoo(DT, gear)
Run Code Online (Sandbox Code Playgroud)
但这次我收到一条错误消息:
Error: evaluation nested too deeply: infinite recursion / options(expressions=)?
Run Code Online (Sandbox Code Playgroud)
好的,所以eval()导致了问题.我们将其删除:
plotfoo <- function(data, by){
by …Run Code Online (Sandbox Code Playgroud) 我期望cbind.xts并do.call(cbind.xts)以相似的经过时间执行.R2.11,R2.14也是如此.
对于R2.15.2和xts 0.8-8,do.call(cbind.xts,...)变体执行速度非常慢,这有效地破坏了我以前的代码.
正如Josh Ulrich在下面的评论中指出的那样,xts软件包维护者已经意识到了这个问题.与此同时,有一个方便的工作吗?
可重复的例子:
library(xts)
secs <- function (rows, from = as.character(Sys.time()), cols = 1, by = 1)
{
deltas <- seq(from = 0, by = by, length.out = rows)
nacol <- matrix(data = NA, ncol = cols, nrow = rows)
xts(x = nacol, order.by = strptime(from, format = "%Y-%m-%d %X") +
deltas)
}
n <- 20
d1 <- secs(rows=n*100,cols=n)
d2 <- secs(rows=n*100,cols=n)
system.time(cbind.xts(d1,d2))
Run Code Online (Sandbox Code Playgroud)
与
system.time(do.call(cbind.xts, list(d1,d2)))
Run Code Online (Sandbox Code Playgroud) 我想要通过一长串潜在的解释变量,依次回归每个反应变量.而不是粘贴模型公式,我正在考虑使用reformulate(),
如此处所示.
fun()下面的功能似乎完成了工作,适合所需的模型.但请注意,它在其call元素中记录了构造的公式对象的名称而不是其值.
## (1) Function using programmatically constructed formula
fun <- function(XX) {
ff <- reformulate(response="mpg", termlabels=XX)
lm(ff, data=mtcars)
}
fun(XX=c("cyl", "disp"))
#
# Call:
# lm(formula = ff, data = mtcars) <<<--- Note recorded call
#
# Coefficients:
# (Intercept) cyl disp
# 34.66099 -1.58728 -0.02058
## (2) Result of directly specified formula (just for purposes of comparison)
lm(mpg ~ cyl + disp, data=mtcars)
#
# Call:
# lm(formula = …Run Code Online (Sandbox Code Playgroud) 我执行lm()带参数formula,data,na.action,和weights.我的权重存储在数字变量中.
formula = "Response~0+.")时,我得到一个错误,即权重不是合适的长度(即使它是).formula = Response~0+.)的公式时,该函数工作正常. 我在lm()文档中偶然发现了这句话:
所有权重,子集和偏移量的计算方式与公式中的变量相同,即首先在数据中,然后在公式的环境中.
这对我来说很难解释,但我觉得它包含了我的问题的答案.
我试图习惯在R中确定问题.我想在函数glm()内部调用函数,但它不起作用,显然是因为我没有设法修复函数assign()或作用的范围eval().
这是一个简化版本:
ao <- function (y, x, phi = seq (0,1,0.1), dataset, weights) {
logLikvector <- rep(0,length(phi)) # vector of zeros to be replaced thereafter
for (i in 1:length(phi)) { # loop to use glm()
fit <- glm (y ~ x, data = dataset, family = binomial, weights = weights)
logLikvector[i] <- logLik(fit) # get log likelihood
}
logLikvector
}
Run Code Online (Sandbox Code Playgroud)
现在我想在我的数据集上使用函数ao()
ao (y = Prop, x = Age, dataset = mydata, weights = Total) …Run Code Online (Sandbox Code Playgroud) 我今天在R代码中意识到了一种奇怪的行为.我尝试了一个包{boot.StepAIC},其中包含一个用于AIC逐步回归结果的bootstrap函数.但是我认为统计背景不是问题(我希望如此).
我可以使用R顶层的函数.这是我的示例代码.
require(MASS)
require(boot.StepAIC)
n<-100
x<-rnorm(n); y<-rnorm(n,sd=2); z<-rnorm(n,sd=3); res<-x+y+z+rnorm(n,sd=0.1)
dat.test<-as.data.frame(cbind(x,y,z,res))
form.1<-as.formula(res~x+y+z)
boot.stepAIC(lm(form.1, dat.test),dat.test) # should be OK - works at me
Run Code Online (Sandbox Code Playgroud)
但是,我想把它包装在一个自己的函数中.我将数据和公式传递给该函数.但我在boot.stepAIC()中遇到错误:
100个引导样本中的模型拟合失败strsplit中的错误(nam.vars,":"):非字符参数
# custom function
fun.boot.lm.stepAIC<-function(dat,form) {
if(!inherits(form, "formula")) stop("No formula given")
fit.lm<-lm(formula=form,data=dat)
return(boot.stepAIC(object=fit.lm,data=dat))
}
fun.boot.lm.stepAIC(dat=dat.test,form=form.1)
# results in an error
Run Code Online (Sandbox Code Playgroud)
那错误在哪里?我想它必须与当地和全球环境有关,不是吗?
5天仍然没有答案
我一直在努力解决这个问题,任何帮助都会非常感激.我正在尝试编写一个运行几个逐步回归的函数,并将所有这些函数输出到列表中.但是,R在读取我在函数参数中指定的数据集时遇到问题.我在各种电路板上发现了几个类似的错误(这里,这里和这里),但是它们似乎都没有得到解决.这一切都归结为在用户定义的函数中调用step()的一些奇怪问题.我使用以下脚本来测试我的代码.多次运行整个过程,直到出现错误(相信我,它会):
test.df <- data.frame(a = sample(0:1, 100, rep = T),
b = as.factor(sample(0:5, 100, rep = T)),
c = runif(100, 0, 100),
d = rnorm(100, 50, 50))
test.df$b[10:100] <- test.df$a[10:100] #making sure that at least one of the variables has some predictive power
stepModel <- function(modeling.formula, dataset, outfile = NULL) {
if (is.null(outfile) == FALSE){
sink(file = outfile,
append = TRUE, type = "output")
print("")
print("Models run at:")
print(Sys.time())
}
model.initial <- …Run Code Online (Sandbox Code Playgroud) 我有一个公式列表,我使用lapply并lm创建一个回归模型列表.但是,当我查看call每个线性模型的组件,而不是看到显式公式时,我会看到我解析为线性模型的变量的名称.例如,使用mtcars数据集:
temp_formula_list = list(as.formula(hp~1),as.formula(hp~cyl))
temp_fm_list = lapply(temp_formula_list, function(x) lm(data = mtcars, formula = x))
Run Code Online (Sandbox Code Playgroud)
然后检查call的temp_fm_list[[2]]:
temp_fm_list[[2]]$call
Run Code Online (Sandbox Code Playgroud)
给
lm(formula = x, data = mtcars)
Run Code Online (Sandbox Code Playgroud)
当我希望它明确给予
lm(formula = hp~cyl, data = mtcars)
Run Code Online (Sandbox Code Playgroud) 我正在编写一个函数,我想将一些参数传递给crrstep-function('crrstep'包),但我遇到了一个问题:当我在crrstep中输入时,我的函数中的参数'event'无法识别.我想crrstep看起来与我想要的环境不同,但即使经过几个小时的网络搜索解决方案,我似乎也无法弄清楚如何解决这个问题(我在编程方面经验不足......) .任何帮助将不胜感激!
这是一些模拟数据(来自crrstep文档的调整示例)和我的代码示例:
n <- 500
ftime <- rexp(n)
fstatus <- sample(0:2,n,replace=TRUE)
testdata <- matrix(runif(8*n),nrow=n)
testdata <- cbind(ftime,fstatus,testdata)
dimnames(testdata)[[2]] <- c('ftime','fstatus','x1','x2','x3','x4','x5','x6','x7','x8')
testdata <- as.data.frame(testdata)
formula1 <- ftime ~ 1 + x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8
rm(fstatus,ftime,n)
test.fun <- function(x,data,event){
require(crrstep)
select.mod<- crrstep(formula=x,,etype=event, failcode=1, cencode=0,data=data,
direction = "backward", criterion = "AIC", crr.object = TRUE,
trace = FALSE)
#Rest of function omitted for now
print(select.mod)
}
#Test
test.fun(x=formula1,data=testdata,event=fstatus)
#I get: Error in …Run Code Online (Sandbox Code Playgroud) 似乎lm()从一个函数内部调用或通过lapply拧紧$call与一个拟合相关联.最小的工作示例:
> library(MASS)
> dat <- data.frame(x = 1:100, y=1:100)
> dat <- within(dat, z <- x + log(y) + rnorm(100))
> fits <- lapply(list(z ~ x + y, z ~ x + log(y)), lm, dat)
> stepAIC(fits[[1]]) # <-- error when I try to use the fit in other functions
Error in eval(expr, envir, enclos) : could not find function "FUN"
> fits[[1]]$call
FUN(formula = X[[i]], data = ..1) # Aha -- this …Run Code Online (Sandbox Code Playgroud)