改进R函数中的for循环

改进R函数中的for循环,r,function,loops,R,Function,Loops,我已经建立了一个基本函数来从3个模型中提取AIC和BIC值,我对几个变量感兴趣。然而,当它运行时,我的计算机经常停止运行,并说它无法将200MB分配给一个向量(我使用的是一个大型数据集,超过500K个案例,是的,我已经将内存限制增加到max-4000) 如果我一次选择几个变量,我实际上已经成功地运行了它。我感兴趣的是一次性运行函数,但同时也要改进我的函数代码,这样我就不必在运行之前删除所有其他内容,也不必等待30分钟。我可能会使用修正的AIC和BIC公式并添加其他内容,因此我宁愿保持AIC和BI

我已经建立了一个基本函数来从3个模型中提取AIC和BIC值,我对几个变量感兴趣。然而,当它运行时,我的计算机经常停止运行,并说它无法将200MB分配给一个向量(我使用的是一个大型数据集,超过500K个案例,是的,我已经将内存限制增加到max-4000)

如果我一次选择几个变量,我实际上已经成功地运行了它。我感兴趣的是一次性运行函数,但同时也要改进我的函数代码,这样我就不必在运行之前删除所有其他内容,也不必等待30分钟。我可能会使用修正的AIC和BIC公式并添加其他内容,因此我宁愿保持AIC和BIC矢量化不变,而不切换到其他逻辑回归函数。我已经尝试过使用它,并添加了类似rm(model1)的东西,但它可能没有什么不同。您能推荐一些代码来解决内存分配问题并可能加速功能吗

非常感谢

职能:

myF
library(difR)
数据(口头)

verbal$TotScore具有离散预测因子的二项式数据的优点是,您可以在不丢失信息的情况下聚合数据

set.seed(12345)
v1<-sample(0:1, 500000, replace=TRUE, prob=c(.80,.20))
v2<-sample(0:1, 500000, replace=TRUE, prob=c(.85,.15))
v3<-sample(0:1, 500000, replace=TRUE, prob=c(.95,.05))
mydata<-as.data.frame(cbind(v1,v2,v3))
mydata$TotScore <- rowSums(mydata)
mydata$group <- rep (1:5,100000)

library(reshape)
myFun2 <- function(Y, dataset){
  tmp <- as.data.frame(table(TotScore = dataset$TotScore, group = dataset$group, Response = dataset[, Y]))
  levels(tmp$Response) <- c("Failure", "Succes")
  tmp <- cast(TotScore + group ~ Response, data  = tmp, value = "Freq")
  tmp$TotScore <- as.numeric(levels(tmp$TotScore))[tmp$TotScore]
  output <- rep(NA, 6)
  names(output) <- paste(rep(c("AIC", "BIC"), 3), rep(0:2, each = 2), sep = "")
  m <- glm(cbind(Succes, Failure) ~ TotScore, data = tmp, family = binomial,
           model = FALSE, x = FALSE, y = FALSE)
  output[1:2] <- c(AIC(m), BIC(m))
  m <- glm(cbind(Succes, Failure) ~ TotScore + group, data = tmp, family = binomial,
           model = FALSE, x = FALSE, y = FALSE)
  output[3:4] <- c(AIC(m), BIC(m))
  m <- glm(cbind(Succes, Failure) ~ TotScore * group, data = tmp, family = binomial,
           model = FALSE, x = FALSE, y = FALSE)
  output[5:6] <- c(AIC(m), BIC(m))
  output
}


system.time({
  sapply(colnames(mydata)[1:3], myFun, dataset = mydata)
})
   user  system elapsed 
  3.10    0.06    3.15 
set.seed(12345)

欢迎来到StackOverflow。也许如果你做了一个演示你的问题,人们会发现它更容易回答。抱歉,附上小数据集示例。我无法显示任何速度提升(我做了类似的事情,但出于这个原因没有发布)。你能详细说明你的解决方案是如何解决内存或速度问题的吗?你可能是对的,但这是我的错,我应该给你一个更大的数据集来尝试,这样你就可以测试大小和时间。我现在修正了这个问题(见上文)。不幸的是,蒂埃里的建议仍然使我的电脑失速,但无论如何,谢谢你改进了功能。亲爱的蒂埃里,谢谢你所有的努力。将数据简化为表格式确实在时间和内存方面有很大的改进。但是,简化(表)数据的AIC和BIC值与完整数据集的值不同,因此我认为它们与其他分析、经验法则等不可比较。如果您在表数据和正常数据上尝试BIC()函数,您就会明白我的意思。BIC尤其“糟糕”,因为完整数据和表格数据的差异不同(而模型之间的AIC差异是相同的,因为它不包括样本大小)。
##Random dataset example
v1<-sample(0:1, 500000, replace=TRUE, prob=c(.80,.20))
v2<-sample(0:1, 500000, replace=TRUE, prob=c(.85,.15))
v3<-sample(0:1, 500000, replace=TRUE, prob=c(.95,.05))
mydata<-as.data.frame(cbind(v1,v2,v3))
TotScore=rowSums(mydata)
group<-(rep (1:5,100000))
myF(mydata,TotScore,group)
library(difR)
data(verbal)
verbal$TotScore <- rowSums(verbal[, c(1:24)])
verbal$group <- with(verbal, factor(Gender):factor(Anger > 20))

myFun <- function(Y, dataset){
  output <- rep(NA, 6)
  names(output) <- paste(rep(c("AIC", "BIC"), 3), rep(0:2, each = 2), sep = "")
  m <- glm(as.formula(paste(Y, "~ TotScore")), data = dataset, family = binomial,
      model = FALSE, x = FALSE, y = FALSE)
  output[1:2] <- c(AIC(m), BIC(m))
  m <- glm(as.formula(paste(Y, "~ TotScore + group")), data = dataset, 
     family = binomial, model = FALSE, x = FALSE, y = FALSE)
  output[3:4] <- c(AIC(m), BIC(m))
  m <- glm(as.formula(paste(Y, "~ TotScore * group")), data = dataset, 
      family = binomial, model = FALSE, x = FALSE, y = FALSE)
  output[5:6] <- c(AIC(m), BIC(m))
  output
}

sapply(colnames(verbal)[1:2], myFun, dataset = verbal)
set.seed(12345)
v1<-sample(0:1, 500000, replace=TRUE, prob=c(.80,.20))
v2<-sample(0:1, 500000, replace=TRUE, prob=c(.85,.15))
v3<-sample(0:1, 500000, replace=TRUE, prob=c(.95,.05))
mydata<-as.data.frame(cbind(v1,v2,v3))
mydata$TotScore <- rowSums(mydata)
mydata$group <- rep (1:5,100000)

library(reshape)
myFun2 <- function(Y, dataset){
  tmp <- as.data.frame(table(TotScore = dataset$TotScore, group = dataset$group, Response = dataset[, Y]))
  levels(tmp$Response) <- c("Failure", "Succes")
  tmp <- cast(TotScore + group ~ Response, data  = tmp, value = "Freq")
  tmp$TotScore <- as.numeric(levels(tmp$TotScore))[tmp$TotScore]
  output <- rep(NA, 6)
  names(output) <- paste(rep(c("AIC", "BIC"), 3), rep(0:2, each = 2), sep = "")
  m <- glm(cbind(Succes, Failure) ~ TotScore, data = tmp, family = binomial,
           model = FALSE, x = FALSE, y = FALSE)
  output[1:2] <- c(AIC(m), BIC(m))
  m <- glm(cbind(Succes, Failure) ~ TotScore + group, data = tmp, family = binomial,
           model = FALSE, x = FALSE, y = FALSE)
  output[3:4] <- c(AIC(m), BIC(m))
  m <- glm(cbind(Succes, Failure) ~ TotScore * group, data = tmp, family = binomial,
           model = FALSE, x = FALSE, y = FALSE)
  output[5:6] <- c(AIC(m), BIC(m))
  output
}


system.time({
  sapply(colnames(mydata)[1:3], myFun, dataset = mydata)
})
   user  system elapsed 
  3.10    0.06    3.15