列表中的功能输入

时间:2015-01-21 07:04:42

标签: r list function dataframe simulation

如何运行一个函数(在R中),其中某些输入是从列表(或数据框)中提取的?我是否正确地认为这比运行for-loop更有效?

我正在运行模拟,并希望更改变量值,但由于它们需要很长时间才能运行,我希望它们能够在一夜之间运行并自动勾选不同的值。

以下是该功能的代码:

n = 10000         
mu = 0                          
sd = 1                          
n.sub = 100                       
iboot = 100
isim = 1000     ### REDUCED FOR THIS EXAMPLE ###
var.values <- NULL         
var.values.pop <- NULL  

hist.fn <- function(n,mu,sd,n.sub,iboot)
{ 
Pop <- rnorm(n,mu,sd)
var.pop <- var(Pop)                       
Samp <- sample(Pop, n.sub, replace = FALSE)  
var.samp <- var(Samp)                                         
for(i in 1:isim) {            
  for(j in 1:iboot) {         
    Boot <- sample(Samp, n.sub, replace = TRUE)           
    var.values[j] <- var(Boot)                                  
    }                                                               
  Samp <- sample(Pop, n.sub, replace = FALSE)         
  var.values.pop[i] <- var(Samp)                                   
  }                                                               
hist.pop <- hist(var.values.pop,plot=F)
hist.boot <- hist(var.values,plot=F)
#mypath = file.path("C:", "Output", paste("hist.boot_n.", n.sub, "_var.", sd^2, "_isim.", isim, "_iboot.", iboot, ".wmf", sep=""))
#win.metafile(file=mypath)
plot.new()   #### ADDED FOR THIS EXAMPLE INSTEAD OF OUTPUTTING TO FILE ####
plot(hist.pop, freq=FALSE, xlim=range(var.values.pop, var.values), ylim=range(hist.pop$density, hist.boot$density), main = paste("Histogram of variances \n n=",n.sub," mu=",mu,"var=",sd^2,"\n n.sim=",isim,"n.boot=",iboot,"\n"), cex.main=0.8, xlab="Variance", col="red") 
plot(hist.boot, freq=FALSE, col="blue", border="blue", add=T, density=20, angle=45) 
abline(v=var.pop, lty=2, col="black", lwd=2)
 legend("topright", legend=c("sample","bootstrap"),col=c("red","blue"),lty=1,lwd=2,bty="n",cex=0.7)
#dev.off()
}

hist.fn(n,mu,sd,n.sub,iboot)

然后我想通过运行以下值来改变sd,n.sub和iboot:

sd <- c(1,10,100,1000)
n.sub <- c(4,10,100,1000)
iboot <- c(100,1000,10000)

3 个答案:

答案 0 :(得分:3)

也许是这样的?

    n = 10000         
    mu = 0                          
    sd = 1                          
    n.sub = 100                       
    iboot = 100
    isim = 1000 
    sd <- c(1,10,100,1000)
    n.sub <- c(4,10,100,1000)
    iboot <- c(100,1000,10000)
    # hist.fn parameters: n,mu,sd,n.sub,iboot
    params <- expand.grid(n = n, mu = mu, sd = sd, 
              n.sub = n.sub, iboot = iboot)
    apply(params, 1, FUN = function(x) do.call(hist.fn, as.list(x) ) )

你可能想把这些:

    var.values <- NULL         
var.values.pop <- NULL  

在hist.fn中,因为为函数外部的变量赋值并不像你想象的那样工作。

答案 1 :(得分:1)

您应该使用do.call,它将使用列表中的参数应用该函数。我简化了您的示例,为示例运行较少的循环。您可以修改脚本的print行,以监控更大工作的进度:

# The function
hist.fn <- function(n,mu,isim,sd,n.sub,iboot)
{ 
  Pop <- rnorm(n,mu,sd)
  var.pop <- var(Pop)                       
  Samp <- sample(Pop, n.sub, replace = FALSE)  
  var.samp <- var(Samp)
  var.values <- NaN*seq(isim) # sets up an empty vector for results
  var.values.pop <- NaN*seq(isim) # sets up an empty vector for results
  for(i in seq(isim)) {            
    for(j in seq(iboot)) {         
      Boot <- sample(Samp, n.sub, replace = TRUE)           
      var.values[j] <- var(Boot) 
      print(paste("i =", i, "; j =", j))
    }                                                               
    Samp <- sample(Pop, n.sub, replace = FALSE)         
    var.values.pop[i] <- var(Samp)                                   
  }                                                               
  list(var.values=var.values, var.values.pop=var.values.pop) #returns results in the form of a list
}

# Global variables
n = 100         
mu = 0                          
isim = 10

# Changing variables
sd <- c(1,10,20,30)
n.sub <- c(4,10,20,30)
iboot <- c(100,200,300,400)

df <- data.frame(sd=sd, n.sub=n.sub, iboot=iboot)
res <- vector(mode="list", nrow(df)) # sets up an empty list for results
for(i in seq(nrow(df))){
  res[[i]] <- do.call(hist.fn, c(n=n, mu=mu, isim=isim, df[i,]) ) 
}
res # show results

答案 2 :(得分:0)

sd <- 1:3
n.sub <- 4:6
iboot <- 7:9

funct1<-function(x,y,z) print(x+y+z)

for (i in 1:length(sd)){
  funct1(sd[i],n.sub[i],iboot[i])
}

只是一个例子。用循环来做。