麻烦传递一个参数在自己的函数内运行 [英] Trouble passing on an argument to function within own function
问题描述
我正在编写一个函数,我想将一些参数传递给crrstep函数('crrstep'包),但是我遇到了一个问题:某种程度上,我的函数中的参数'event'在我输入时无法识别在crrstep。我猜这个crrstep看起来和我想要的不一样,但即使在网上搜索解决方案几个小时之后,我似乎也无法弄清楚如何解决这个问题(我在编程方面很缺乏经验)。 。任何帮助将不胜感激!
以下是一些模拟数据(来自crrstep-documentation的调整示例)和我的代码示例:
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)
#现在遗漏的功能
print(select.mod)
}
#Test
test.fun(x = formula1,data = testdata,event = fstatus)
#I get:eval中的错误(expr,envir,enclos):object'event'not找到
非常感谢!
Rob
在函数内调用依赖于数据框中名称评估的函数时,我使用 do.call
,它在传递给函数之前对它的参数进行求值,因此使得调试和编写代码变得更简单,我觉得我可以更确定它在做什么。 (对于调试,只需使用调用
而不是 do.call
,它将显示函数将尝试运行的内容;语法也有点不同,所以当这样做的时候,也要删除调用中的列表结构。)
(请看Josh O'Brien在这里的回答: https://stackoverflow.com/a/7668846/210673 )
test.fun< - function(x,data,event)在这种情况下,它看起来像这样: ){
require(crrstep)
select.mod< - do.call(crrstep,
list(formula = x,etype = substitute(event),failcode = 1,cencode = 0,
data = as.name(data),direction =backward,criterion =AIC,
crr.object = TRUE,trace = FALSE))
print (select.mod)
}
test.fun(x = formula1,data = testdata,event = fstatus)
下面是使用 以下是一个示例数据集和对 自然的方式,因为它在数据框中寻找 可以使用字符串构建调用;这是一个更直截了当的: 或者可以使用 但是我也可以在函数中使用 它同样适用于实际的数据框架,但通话时间更长。但是,如果您在每次调用之前以编程方式更改数据框并希望记录该数据框是什么,则可能需要这样做。 (然而,我的偏好是,如果你确实希望以后能更清楚地保存这个数据框)。 再次证明您不能只使用 I am writing a function in which I want to pass some arguments to the crrstep-function ('crrstep' package), but I encountered a problem: somehow the argument 'event' in my function is not recognized when I enter it in crrstep. I guess that crrstep looks in a different environment than the one I want it to look, but even after hours of searching for solutions on the web, I cannot seem to figure out how to solve this (I am quite inexperienced in programming..). Any help would be greatly appreciated! Here is some simulation data (adjusted example from crrstep-documentation) and an example of my code: Many thanks!
Rob When calling functions within functions that depend on evaluating names within a data frame, I use (Credit to Josh O'Brien's answer here for this idea: https://stackoverflow.com/a/7668846/210673) In this case, it would look like this: The Here's an example of very similar behavior using Here's an example data set and the call to The natural way, which doesn't work because it's looking for One can build the call with strings; this is a little more straightforward: Or one can use But I could also use It works to put in the actual data frame as well, but the call is longer. This however, might be desired if you're changing the data frame programatically before each call and want to have a record of what that data frame is. (My preference, though, would be to save that data frame in a more explicit way, if you really do want it later.) One more to show that you can't just use
这篇关于麻烦传递一个参数在自己的函数内运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! event
。 as.name(data)
指示它在函数中寻找 data
,而不是传递实际的数据帧。另一个选项是 substitute(data)
,它将查找您拥有的实际数据框。 使用 lm
lm
和权重
参数:
lm
,不在另一个函数中。我打印响应的调用
元素以查看它实际做了什么。
> set.seed(5)
> dd < - data.frame(x = 1:10,y = round(rnorm(10,mean = 10),1),z = round(runif(10,1,4),1))
> lm(y〜x,权重= z,data = dd)$ call
lm(formula = y〜x,data = dd,weights = z)
w
,所以不起作用:
> f1 < - 函数(f,w,d){
+ lm(公式= f,权重= w,数据= d)
+}
> f1(y〜x,z,dd)
eval中的错误(expr,envir,enclos):找不到对象'w'
> f2 < - 函数(f,w,d){
+ do.call(lm,list(formula = as.formula(f),weights = as.name(w),data = as。姓名(d)))
+}
> f2(y〜x,z,dd)$ call
lm(formula = y〜x,data = dd,weights = z)
替代
;在这里我调用函数中的实际数据集 dd
,而不是函数内的 d
。如果我想使用 update
,这可能会很有用。
> ; f3 < - 函数(f,w,d){
+ do.call(lm,list(formula = f,weights = substitute(w),data = substitute(d)))
+}
> f3(y〜x,z,dd)$ call
lm(formula = y〜x,data = dd,weights = z)
d
;这次注意调用 data = d
而不是 data = dd
。
> f4 < - 函数(f,w,d){
+ do.call(lm,list(formula = f,weights = substitute(w),data = as.name(d)) )
+}
> f4(y〜x,z,dd)$ call
lm(formula = y〜x,data = d,weights = z)
> f5 < - 函数(f,w,d){
+ do.call(lm,list(formula = f,weights = substitute(w),data = d))
+}
> f5(y〜x,z,dd)$ call
lm(公式= y〜x,data = list(x = 1:10,y = c(9.2,11.4,8.7,
10.1, ),z = c(3.7,3.2,1.6,1.7,
1.4,2.4,2.3,3.9,1.4,3.9)),权重= z)
替换
substitute
会在 lm
。
> (公式= f,权重=替代(w),数据= d)
+}
>(函数(f,w,d) f6(y〜x,z,dd)
model.frame.default中的错误(公式= f,data = d,weights = substitute(w),:
变量的无效类型(符号) (权重)'
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 eval(expr, envir, enclos) : object 'event' not found"
do.call
, which evaluates its arguments before passing to the function and so makes both debugging and writing the code simpler, and I feel like I can be more sure about what it's doing. (For debugging, just use call
instead of do.call
, which will show what the function will try to run; the syntax is also a little different so when doing this remove the list structure within the call as well.)test.fun <- function(x, data, event){
require(crrstep)
select.mod <- do.call("crrstep",
list(formula=x, etype=substitute(event), failcode=1, cencode=0,
data=as.name("data"), direction = "backward", criterion = "AIC",
crr.object = TRUE, trace = FALSE))
print(select.mod)
}
test.fun(x=formula1, data=testdata, event=fstatus)
substitute(event)
tells it to use the name that was given to the function, not the name event
. The as.name("data")
tells it to look for data
within the function instead of passing the actual data frame. Another option is substitute(data)
which will look for the actual data frame you have.an example using
lm
lm
and the weights
argument:lm
, not within another function. I print the call
element of the response to see what it actually did.> set.seed(5)
> dd <- data.frame(x=1:10,y=round(rnorm(10,mean=10),1), z=round(runif(10,1,4),1))
> lm(y~x, weights=z, data=dd)$call
lm(formula = y ~ x, data = dd, weights = z)
w
in the data frame:> f1 <- function(f,w,d){
+ lm(formula=f,weights=w, data=d)
+ }
> f1(y~x, z, dd)
Error in eval(expr, envir, enclos) : object 'w' not found
> f2 <- function(f,w,d){
+ do.call("lm", list(formula=as.formula(f), weights=as.name(w), data=as.name(d)))
+ }
> f2("y~x", "z", "dd")$call
lm(formula = y ~ x, data = dd, weights = z)
substitute
; here I'm calling the function on my actual data set dd
, not the d
within the function. This might be useful later if I want to use update
.> f3 <- function(f,w,d){
+ do.call("lm", list(formula=f, weights=substitute(w), data=substitute(d)))
+ }
> f3(y~x, z, dd)$call
lm(formula = y ~ x, data = dd, weights = z)
d
within the function; this time notice that data = d
in the call instead of data = dd
.> f4 <- function(f,w,d){
+ do.call("lm", list(formula=f, weights=substitute(w), data=as.name("d")))
+ }
> f4(y~x, z, dd)$call
lm(formula = y ~ x, data = d, weights = z)
> f5 <- function(f,w,d){
+ do.call("lm", list(formula=f, weights=substitute(w), data=d))
+ }
> f5(y~x, z, dd)$call
lm(formula = y ~ x, data = list(x = 1:10, y = c(9.2, 11.4, 8.7,
10.1, 11.7, 9.4, 9.5, 9.4, 9.7, 10.1), z = c(3.7, 3.2, 1.6, 1.7,
1.4, 2.4, 2.3, 3.9, 1.4, 3.9)), weights = z)
substitute
without do.call
as the substitute
is executed within the call to lm
.> f6 <- function(f,w,d){
+ lm(formula=f,weights=substitute(w), data=d)
+ }
> f6(y~x, z, dd)
Error in model.frame.default(formula = f, data = d, weights = substitute(w), :
invalid type (symbol) for variable '(weights)'