Search code examples
rgpsanalysistelemetry

Trying to generate and store multiple KDE models in R


I am working with a point dataset that includes data from several gps collars on animals with unique identification numbers.

What I am trying to do is model their ranges using Kernel Density Estimator for each animal. What I have produces a graph of each model but I need to save the actual estimator for each one for further analyses. I'm going to reveal my ignorance here, but I tried to do this with a for loop.

collars<-unique(gps$CollarID)

where gps is my dataframe

for (i in 1:length(collars)){
    collar<-subset(gps, CollarID == collars[i], select=c(Easting, Northing))
    cxy<-cbind(collar$Easting,collar$Northing)
    kde<-kde(cxy)
    plot(kde, xlab = "X", ylab = "Y")
    title(main = collars[i])
}

What I am after is producing a uniquely named kde object for each itteration. I have tried to include the counter in the name of the object, but quickly found that that did not work.

Any help would be greatly appreciated!

-JF


Solution

  • Using dplyr, you could wrap the calculations in a function that calculates kde for each Easting, Northing observation and save resultant kde objects in list to be plotted by a separate function

    Since we do not have the sample dataset, I have used mtcars dataset.

    #load libraries, assuming you are using kde function from "ks" library
    library("dplyr")
    library("lazyeval") #required for interp function
    library("ks")
    
    
    
    DF = mtcars
    indexColName = "cyl"
    indexVar = unique(DF[,indexColName])
    calcVars = c("hp","wt")
    
    
    ### Replacement values for your dataset ###
    
    # DF = gps
    # indexColName = "CollarID"
    # indexVar = unique(DF[,indexColName])
    # calcVars = c("Easting","Northing")
    

    kde calc function:

    fn_kdeCalc <- function(indexVarInput = indexVar,indexColInput = indexColName,calcVarsInput=calcVars) {
    
    cat("Begin kde calc for",indexColInput,"=",indexVarInput,"\n")
    
    #filter condition logic translates as CollarID == collars[i]
    #the following is required for dynamic inputs , you can read more from trying, vignette("nse")
    
    filter_criteria <- interp(~ filter_column == indexVarInput, filter_column = as.name(indexColInput))
    
    kdeObj <- DF %>% 
            dplyr::filter_(filter_criteria) %>%           # subset dataset to specific filter condition
            dplyr::select(one_of(calcVarsInput)) %>%      # select specific columns for kde calc
            kde()                                         # calculate kde for selected variables
    
    cat("End kde calc for",indexColInput,"=",indexVarInput,"\n")
    
    return(kdeObj)
    
    }
    
    #calculate kde for each unique input variable using above function and save in a list
    
    kdeObjList = lapply(indexVar,function(x) { 
    
    fn_kdeCalc(indexVarInput = x,indexColInput = indexColName,calcVarsInput=calcVars) 
    
    })
    

    kde plot function:

    fn_kdePlot = function(kdeObject = NULL,titleObj = NULL,labelVars=calcVars) {
      plot(kdeObject, xlab = labelVars[1], ylab = labelVars[2],main = paste0("Kernel Density estimation for ",indexColName,":",titleObj) )
    }
    
    
    
    ### save plots ###
    # you can use png() to save in different file for each plot or 
    # pdf("KDE_plots1.pdf") to include them in one file
    
    png()
    
    lapply(1:length(kdeObjList), function(x) fn_kdePlot(kdeObject = kdeObjList[[x]],titleObj = indexVar[x]) )
    
    dev.off()
    

    enter image description here enter image description here enter image description here