R中函数中的函数

R中函数中的函数,r,R,你能解释一下为什么代码抱怨没有找到Samdat 我正在尝试在模型之间切换,因此我声明了一个包含这些特定模型的函数,我只需要调用此函数作为get.f函数中的参数之一,其中重采样将更改模型中每个设计矩阵的结构。代码抱怨在找到Samdat时未找到它 还有,有没有一种方法可以使条件语句if(Model==M1())而不必创建另一个参数M来设置if(M==1) 这是我的密码: dat <- cbind(Y=rnorm(20),rnorm(20),runif(20),rexp(20),rnorm(2

你能解释一下为什么代码抱怨没有找到
Samdat

我正在尝试在模型之间切换,因此我声明了一个包含这些特定模型的函数,我只需要调用此函数作为
get.f
函数中的参数之一,其中重采样将更改模型中每个设计矩阵的结构。代码抱怨在找到Samdat时未找到它

还有,有没有一种方法可以使条件语句
if(Model==M1())
而不必创建另一个参数
M
来设置
if(M==1)

这是我的密码:

dat <-  cbind(Y=rnorm(20),rnorm(20),runif(20),rexp(20),rnorm(20),runif(20), rexp(20),rnorm(20),runif(20),rexp(20))
nam <- paste("v",1:9,sep="")
colnames(dat) <- c("Y",nam)

M1 <- function(){
    a1 = cbind(Samdat[,c(2:5,7,9)])
    b1 = cbind(Samdat[,c(2:4,6,8,7)])
    c1 = b1+a1
    list(a1=a1,b1=b1,c1=c1)}

M2 <- function(){
    a1= cbind(Samdat[,c(2:5,7,9)])+2
    b1= cbind(Samdat[,c(2:4,6,8,7)])+2
    c1 = a1+b1
    list(a1=a1,b1=b1,c1=c1)}

M3 <- function(){
    a1= cbind(Samdat[,c(2:5,7,9)])+8
    b1= cbind(Samdat[,c(2:4,6,8,7)])+8
    c1 = a1+b1
    list(a1=a1,b1=b1,c1=c1)}
#################################################################
get.f <- function(asim,Model,M){
    sse <-c()
    for(i in 1:asim){
        set.seed(i)
        Samdat <- dat[sample(1:nrow(dat),nrow(dat),replace=T),]
        Y <- Samdat[,1]
        if(M==1){
            a2 <- Model$a1
            b2 <- Model$b1
            c2 <- Model$c1
            s<- a2+b2+c2
            fit <- lm(Y~s)
            cof <- sum(summary(fit)$coef[,1])
            coff <-Model$cof
            sse <-c(sse,coff)
        }
        else if(M==2){
            a2 <- Model$a1
            b2 <- Model$b1
            c2 <- Model$c1
            s<- c2+12
            fit <- lm(Y~s)
            cof <- sum(summary(fit)$coef[,1])
            coff <-Model$cof
            sse <-c(sse,coff)
        }
        else {
            a2 <- Model$a1
            b2 <- Model$b1
            c2 <- Model$c1
            s<- c2+a2
            fit <- lm(Y~s)
            cof <- sum(summary(fit)$coef[,1])
            coff <- Model$cof
            sse <-c(sse,coff)
        }
    }
    return(sse)
}

get.f(10,Model=M1(),M=1)
get.f(10,Model=M2(),M=2)
get.f(10,Model=M3(),M=3)

dat您可能想看看。特别是,没有理由期望在函数中定义的变量在其他函数中可见

您可能会感到困惑,因为全局环境(即所有函数之外的顶级环境)是此规则的一个例外。我不打算讨论你的其他问题,但让我注意到,整个脚本在我看来非常混乱-即,
M1
to
M3
基本上是一个函数,而在
get.f
中复制/粘贴的过程肯定很糟糕。无论你想做什么,都可以用一种不太复杂的方式来写

让我们先看一下
M
s-为什么不使用一个带参数的函数?包括范围问题的解决方案,这将产生两个参数-

M <- function(sampleData, offset) { 
    a1 = sampleData[,c(2:5,7,9)] + offset
    b1 = sampleData[,c(2:4,6,8,7)] + offset
    c1 = b1+a1
    list(a1=a1,b1=b1,c1=c1)
}
这仍然是非常重复的,所以我们为什么不考虑一下呢?您对样本所做的只是从中计算出一列,以适合您的需要。我不明白为什么您需要在
M
函数中进行计算,然后在
get.f
中提取单个值(取决于您使用的特定M)-这似乎表明提取应该更像是M的一部分。。。但如果需要将它们分开,好的,让我们使用单独的提取函数。在合理编写的R中,仍然不到代码大小的一半:

# Set up test data
dat <-  cbind(Y=rnorm(20),rnorm(20),runif(20),rexp(20),rnorm(20),runif(20), rexp(20),rnorm(20),runif(20),rexp(20))
nam <- paste("v",1:9,sep="")
colnames(dat) <- c("Y",nam)

# calculate a1..c1 from a sample
M <- function(sampleData, offset) { 
    a1 = sampleData[,c(2:5,7,9)] + offset
    b1 = sampleData[,c(2:4,6,8,7)] + offset
    c1 = b1+a1
    list(a1=a1,b1=b1,c1=c1)
}

# create a fixed-offset model from the variable offset model by fixing offset
makeModel <- function(offset) function(sampleData) M(sampleData, offset)   

# run model against asim subsamples of data and collect coefficients
get.f <- function(asim,model,expected) 
    sapply(1:asim,  function (i){
        set.seed(i)
        Samdat <- dat[sample(1:nrow(dat),nrow(dat),replace=T),]
        Y <- Samdat[,1]
        s <- expected(model(Samdat))
        fit <- lm(Y~s)
        sum(summary(fit)$coef[,1])
    })

# list of models to run and how to extract the expectation values from the model reslts
todo <- list(
        list(model=makeModel(0), expected=function(data) data$a1+data$b1+data$c1),
        list(model=makeModel(2), expected=function(data) data$c1+12),
        list(model=makeModel(8), expected=function(data) data$c1+data$a1))

sapply(todo, function(l) { get.f(10, l$model, l$expected)})
#设置测试数据
当你打电话的时候

get.f(10, Model=M1(), M=1)
立即调用您的
M1
函数。它死机是因为在
M1
的主体中,您正在使用
Samdat
,它只在后面的
get.f
主体中定义

不知何故,您需要在定义了
Samdat
之后调用
M1
。一种方法是将
M1
(函数)作为
get.f
的参数,并从
get.f
内部调用函数:

get.f <- function(asim, Model.fun, M) {
   ...
   Sambat <- ...
   Model  <- Model.fun()
   ...
}
get.f(10, Model.fun = M1, M=1)

跳出来的最后一件事是:如果
s
的定义(我在
开关()下收集的内容)< /代码>与<代码>模型< /代码>有关,然后考虑合并<代码>模型> <代码>和<代码> s>代码>一起:将<代码> s >代码>添加到<代码> M1<代码>的列表输出中,<代码> M2,<代码> M3< /代码>函数,以便<代码> s >代码>可以被定义为<代码> s。函数开始和结束?也许这也能帮助你解决问题。我用一行空格分隔,你说的Reindent是什么意思?我的意思正是Jilber为你做的。缩进不是我做的,是@themel,credits为他做的。:)谢谢你的回答。我试着创建一个与我尝试做的类似的例子。第一:函数M1-M3相似,但不相同,我给每个函数添加了不同的常数。然而,在实际工作中,我正在编码它们有不同的矩阵。我想做的是在get.f函数中调用这些函数(M1-M3),用M1-M3创建新的矩阵。我会在采样数据后这样做,这样我才能适应新模型。我不明白你说的最可怕的部分是什么。我有更多的M1-M3(有M1-M30),所以我不能只在get.f函数中编写它们。第一个用于对数据进行采样,并为采样数据创建不同的矩阵。然后在第二个脚本中,我创建了模型函数(M1-M3),它包含不同的矩阵并检查一些结果。第三个脚本我创建了get.f,以根据第二个脚本中的这些不同矩阵来适应不同的模型。我的主要目标是实现SSE成果。我有大约3000个专栏
# Set up test data
dat <-  cbind(Y=rnorm(20),rnorm(20),runif(20),rexp(20),rnorm(20),runif(20), rexp(20),rnorm(20),runif(20),rexp(20))
nam <- paste("v",1:9,sep="")
colnames(dat) <- c("Y",nam)

# calculate a1..c1 from a sample
M <- function(sampleData, offset) { 
    a1 = sampleData[,c(2:5,7,9)] + offset
    b1 = sampleData[,c(2:4,6,8,7)] + offset
    c1 = b1+a1
    list(a1=a1,b1=b1,c1=c1)
}

# create a fixed-offset model from the variable offset model by fixing offset
makeModel <- function(offset) function(sampleData) M(sampleData, offset)   

# run model against asim subsamples of data and collect coefficients
get.f <- function(asim,model,expected) 
    sapply(1:asim,  function (i){
        set.seed(i)
        Samdat <- dat[sample(1:nrow(dat),nrow(dat),replace=T),]
        Y <- Samdat[,1]
        s <- expected(model(Samdat))
        fit <- lm(Y~s)
        sum(summary(fit)$coef[,1])
    })

# list of models to run and how to extract the expectation values from the model reslts
todo <- list(
        list(model=makeModel(0), expected=function(data) data$a1+data$b1+data$c1),
        list(model=makeModel(2), expected=function(data) data$c1+12),
        list(model=makeModel(8), expected=function(data) data$c1+data$a1))

sapply(todo, function(l) { get.f(10, l$model, l$expected)})
get.f(10, Model=M1(), M=1)
get.f <- function(asim, Model.fun, M) {
   ...
   Sambat <- ...
   Model  <- Model.fun()
   ...
}
get.f(10, Model.fun = M1, M=1)
M1 <- function(sampled.data) {
   a1 <- sampled.data[, c("v1", "v2", "v3", "v4", "v6", "v8")]
   b1 <- sampled.data[, c("v1", "v2", "v3", "v5", "v7", "v6")]
   c1 <- a1 + b1
   list(a1 = a1, b1 = b1, c1 = c1)
}

get.f <- function(dat, asim, Model.fun, offset, M) {
   sse <- c()
   for(i in 1:asim){
      set.seed(i)
      Samdat <- dat[sample(1:nrow(dat), nrow(dat), replace = TRUE), ]
      Y      <- Samdat[, "Y"]
      Model  <- Model.fun(sampled.data = Samdat)
      a2     <- Model$a1
      b2     <- Model$b1
      c2     <- Model$c1      
      s      <- switch(M, a2 + b2 + c2, c2 + 12, c2 + a2)
      fit    <- lm(Y ~ s)
      cof    <- sum(summary(fit)$coef[,1])
      coff   <- Model$cof        # there is a problem here...
      sse    <- c(sse, coff)     # this is not efficient
   }
   return(sse)
}

dat <- cbind(Y = rnorm(20), v1 = rnorm(20), v2 = runif(20), v3 = rexp(20),
                            v4 = rnorm(20), v5 = runif(20), v6 = rexp(20),
                            v7 = rnorm(20), v8 = runif(20), v9 = rexp(20))

get.f(dat, 10, Model.fun = M1, M = 1)