For my internship I have to perform certain analysis to determine residuals and outliers. The table I'm currently using has over 12 million records with 130+ columns.

My first tests take approx. 5398 seconds or 1.5 hours to apply the module and establish outliers and put them into a plot. The goal of my project is performing analysis on 14-20 similar models within an hour (on a better server, though).

I just changed the `glm()` to `lm()` and the process time went down from 1.5hr to 15 minutes. 

I also got the following details from `Rprof()`:

> 		$by.self
> 								self.time self.pct total.time total.pct
> 		"lm.fit"                   920.64    99.16     921.56     99.26
> 		".Call"                      1.48     0.16       1.48      0.16
> 		"plot.xy"                    1.22     0.13       1.22      0.13
> 		".External2"                 1.10     0.12       1.52      0.16
> 		"colnames<-"                 0.92     0.10       0.92      0.10
> 		".External"                  0.88     0.09       0.88      0.09
> 		"as.character"               0.66     0.07       0.66      0.07
> 		"unique.default"             0.18     0.02       0.24      0.03
> 		"strsplit"                   0.18     0.02       0.18      0.02
> 		"[.data.frame"               0.16     0.02       0.18      0.02
> 		"match"                      0.12     0.01       0.12      0.01
> 		"sort.int"                   0.12     0.01       0.12      0.01
> 		"Determine_bounds"           0.08     0.01     927.86     99.94
> 		"na.omit"                    0.08     0.01       0.42      0.05
> 		"FUN"                        0.08     0.01       0.34      0.04
> 		"na.omit.data.frame"         0.08     0.01       0.34      0.04
> 		"is.na"                      0.08     0.01       0.08      0.01
> 		"is.factor"                  0.06     0.01       0.06      0.01
> 		"lapply"                     0.04     0.00       0.38      0.04
> 		"anyNA"                      0.04     0.00       0.04      0.00
> 		"readLines"                  0.04     0.00       0.04      0.00
> 		"model.matrix.default"       0.02     0.00       1.24      0.13
> 		"model.response"             0.02     0.00       0.68      0.07
> 		"anyDuplicated.default"      0.02     0.00       0.02      0.00
> 		"as.double"                  0.02     0.00       0.02      0.00
> 		"lazyLoadDBfetch"            0.02     0.00       0.02      0.00
> 		"max"                        0.02     0.00       0.02      0.00
> 		"pmatch"                     0.02     0.00       0.02      0.00
> 		"table"                      0.02     0.00       0.02      0.00
> 		$by.total
> 								total.time total.pct self.time self.pct
> 		"Determine_bounds"          927.86     99.94      0.08     0.01
> 		"main"                      927.86     99.94      0.00     0.00
> 		"lm"                        924.00     99.53      0.00     0.00
> 		"lm.fit"                    921.56     99.26    920.64    99.16
> 		".External2"                  1.52      0.16      1.10     0.12
> 		".Call"                       1.48      0.16      1.48     0.16
> 		"dbGetQuery"                  1.48      0.16      0.00     0.00
> 		"DbQuery"                     1.48      0.16      0.00     0.00
> 		"doTryCatch"                  1.48      0.16      0.00     0.00
> 		".local"                      1.48      0.16      0.00     0.00
> 		".oci.GetQuery"               1.48      0.16      0.00     0.00
> 		"standardGeneric"             1.48      0.16      0.00     0.00
> 		"try"                         1.48      0.16      0.00     0.00
> 		"tryCatch"                    1.48      0.16      0.00     0.00
> 		"tryCatchList"                1.48      0.16      0.00     0.00
> 		"tryCatchOne"                 1.48      0.16      0.00     0.00
> 		"plot"                        1.26      0.14      0.00     0.00
> 		"plot.default"                1.26      0.14      0.00     0.00
> 		"model.matrix.default"        1.24      0.13      0.02     0.00
> 		"model.matrix"                1.24      0.13      0.00     0.00
> 		"plot.xy"                     1.22      0.13      1.22     0.13
> 		"colnames<-"                  0.92      0.10      0.92     0.10
> 		".External"                   0.88      0.09      0.88     0.09
> 		"dev.off"                     0.84      0.09      0.00     0.00
> 		"model.response"              0.68      0.07      0.02     0.00
> 		"as.character"                0.66      0.07      0.66     0.07
> 		"summaryRprof"                0.52      0.06      0.00     0.00
> 		"<Anonymous>"                 0.44      0.05      0.00     0.00
> 		"eval"                        0.44      0.05      0.00     0.00
> 		"model.frame.default"         0.44      0.05      0.00     0.00
> 		"na.omit"                     0.42      0.05      0.08     0.01
> 		"lapply"                      0.38      0.04      0.04     0.00
> 		"FUN"                         0.34      0.04      0.08     0.01
> 		"na.omit.data.frame"          0.34      0.04      0.08     0.01
> 		"unique.default"              0.24      0.03      0.18     0.02
> 		"factor"                      0.20      0.02      0.00     0.00
> 		"strsplit"                    0.18      0.02      0.18     0.02
> 		"[.data.frame"                0.18      0.02      0.16     0.02
> 		"["                           0.18      0.02      0.00     0.00
> 		"quantile"                    0.16      0.02      0.00     0.00
> 		"quantile.default"            0.16      0.02      0.00     0.00
> 		"match"                       0.12      0.01      0.12     0.01
> 		"sort.int"                    0.12      0.01      0.12     0.01
> 		"sort"                        0.12      0.01      0.00     0.00
> 		"sort.default"                0.12      0.01      0.00     0.00
> 		"is.na"                       0.08      0.01      0.08     0.01
> 		"as.factor"                   0.08      0.01      0.00     0.00
> 		"diff"                        0.08      0.01      0.00     0.00
> 		".getXlevels"                 0.08      0.01      0.00     0.00
> 		"IQR"                         0.08      0.01      0.00     0.00
> 		"levels"                      0.08      0.01      0.00     0.00
> 		"unique"                      0.08      0.01      0.00     0.00
> 		"is.factor"                   0.06      0.01      0.06     0.01
> 		"anyNA"                       0.04      0.00      0.04     0.00
> 		"readLines"                   0.04      0.00      0.04     0.00
> 		"pdf"                         0.04      0.00      0.00     0.00
> 		"sapply"                      0.04      0.00      0.00     0.00
> 		"anyDuplicated.default"       0.02      0.00      0.02     0.00
> 		"as.double"                   0.02      0.00      0.02     0.00
> 		"lazyLoadDBfetch"             0.02      0.00      0.02     0.00
> 		"max"                         0.02      0.00      0.02     0.00
> 		"pmatch"                      0.02      0.00      0.02     0.00
> 		"table"                       0.02      0.00      0.02     0.00
> 		"anyDuplicated"               0.02      0.00      0.00     0.00
> 		"deparse"                     0.02      0.00      0.00     0.00
> 		".deparseOpts"                0.02      0.00      0.00     0.00
> 		"paste"                       0.02      0.00      0.00     0.00
> 		"range"                       0.02      0.00      0.00     0.00
> 		"xy.coords"                   0.02      0.00      0.00     0.00
> 		$sample.interval 		[1] 0.02
> 		$sampling.time 		[1] 928.4

The R code:

     #include libraries
     library(DBI)
     library(ROracle)
     library(outliers)
     library(Rmisc)
     library(data.table)
     #set params
     options(width=10000, error=traceback)
     args <- commandArgs()
     #print(args)
     debug <-F
    
     ### Connect to database
     drv <- dbDriver("Oracle")
     con <- dbConnect(drv, username="DB USER", password="DB PASS", dbname="DB NAME")
    
    
    
     main <- function(){
             #Data_table  = "BPM_FINISHING_DATA"
             Data_table = "TBL_TRAINING_SET"
             print(paste("Performing queries against", Data_table))
             AllTraits = "BACKFAT_CARCASS"
                     if(debug){cat("\n\n")}
                     ptm <- proc.time()
             a <- Determine_bounds(Data_table)
                     tijd <- proc.time() - ptm
                     cat("\n")
                     cat(paste("\t",tijd['elapsed'][1]))
    
    
    
     }
    
    
     Determine_bounds <- function(Data_table){
             ### Create query
             sqlstr <- paste("
                     select PIG_ID,
                             coalesce(to_char(trial_tstart), to_char(trial_tmed), to_char(trial_tend)) \"trial\",
                             bln_tend_sex_lgp_itn \"farm_tend\",
                             gain_tstart_tend \"gain\",
                             BREEDING_LINE,
                             SEX_CODE,
                             bln_cmt_tstart_itn \"farmcomp\",
                             --coalesce(bln_cmt_tstart_itn, hys_birth_tend, HYS_CGG) \"farmcomp\",
                             birth_weight_scaled
                     from
                             ",Data_table,"
                    where
                             EBT_TSTART = 'Y'
                             AND EBT_TEND = 'Y'
                     ")
             if(Data_table == "BPM_FINISHING_DATA"){
                     sqlstr <- paste(sqlstr, " AND FINISHER_YN = 'N'")
             }
    
             cat(format(sqlstr))
             ### Run query against database
             res <- DbQuery(sqlstr)
             res$trial[is.na(res$trial)] <-"XXX"
             res$farm_trend[is.null(res$farm_trend)] <- -9
             res$birth_weight_scaled[is.null(res$birth_weight_scaled)] <- -9
    
    
             lmfit = lm(res$gain ~ res$trial + res$farm_trend * res$BREEDING_LINE* res$SEX_CODE + res$birth_weigh    t_scaled)#+res$farmcomp)
    
             kwant <- quantile(resid(lmfit), probs= c(0.25, 0.75))
             Q1 <- kwant[1]
             Q3 <- kwant[2]
             sigma <- IQR(resid(lmfit))
             upp_multi <- 3.5        ##Amount of times sigma for outlier calculation
             low_multi <- 1.5        ##Amount of times sigma for outlier calculation
    
             upp_fence <- Q3+(upp_multi * sigma)
             low_fence <- Q1-(low_multi * sigma)
             print(paste("Upper fence: ", upp_fence, " \t  Lower Fence: ", low_fence ,"\n"))
    
    
    
     		pdf('~/scripts/PlotResiduals.pdf')
     		plot(resid(lmfit),ylim=c(low_fence*2,upp_fence *2), axes=F )
     		title(main="Outliers", sub="X axis title")
     		abline(h= upp_fence, col="blue")
     		abline(h= low_fence, col="red")
    			dev.off()
    
     		
    
    
    
    
     }
    
    
     DbQuery <- function(sqlstr){
             res <- dbGetQuery(con, sqlstr)
             return(res)
     }
    
     main()
     dbDisconnect(con)
    
     q()

Right now I've scripted the following code and I was wondering. Where could the code below be improved the most? (I know I'm not the best coder, but always trying to learn and improve.)

I am currently reading [these][1] [two][2] PDFs about performance but I'd still like some feedback.


[1]: http://www.burns-stat.com/pages/Tutor/R_inferno.pdf
[2]: http://www.bioconductor.org/help/course-materials/2010/BioC2010/EfficientRProgramming.pdf