Search code examples
rself-organizing-maps

Accessing R Self Organizing Map Codebook Vectors


I am working to use SOMs to help analyze variability of weather forecast model ensembles. To do so, access a 20 ensemble global weather forecast model over a specific geographic domain. I convert a 20 x Nlat x Nlon matrix to a 20 x Nlat*Nlon matrix, present it to the Kohonen package som function. I then seek to access the som "codebook vector" output and transform it back to the latitude longitude grid. I am, however, receiving an error message at this step.

The error message I recieve is: 'Error in var.som$codes[i, ] : incorrect number of dimensions.' In this case, var.som is the Kohonen object. I loop from N = 1:Nsom, where Nsom is the number of "maps" specified in the call to the som function.

The attribute data for var.som indicates the size of the list var.som$codes is "num [1:4, 1:500]", suggesting two dimensions, which is why I think my code should work. I have tried different permutations to access the list data but none work. I.e. var.som$codes[1], and var.som$codes[[1]] but they do not solve the problem. var.som$codes[1,1] yields NULL.

In the R script below, I have reduced the process to only the essential steps. A random number generator replaces the accessing of the weather model data. In the code, I indicate the location of where the error occurs and what the error message is.

Help and guidance for how to access the var.som$codes one codebook vector at a time is appreciated.

# An R script that provides an example of using a Self Organizing Map to calucate a SOM from latitude/longitude
# data.  An error occurs fails accessing the SOM data vector codes.   

library("kohonen")

# Set a few parameters 
Nlon <- 20  # Number of longitude points
Nlat <- 25  # Number of latitude points
Nens <- 20  # number of ensemble members
Nsom <- 4   # number of "maps" in SOM

t2m.en <- as.list(rep(0,Nens))


# Generate Nlon * Nlat random numbers for Nens ensembles 
for (i in 1:Nens)  {
        t2m.en[[i]] <- runif(Nlon*Nlat, -5, 5)
  }

#array containing ensemble data
t2m.ens <- array(unlist(t2m.en),dim=c(20,Nlon,Nlat))
t2m.vec <- matrix(t2m.ens, nrow=20, ncol=Nlat*Nlon, byrow=TRUE)

# remove the column mean from each column of data (i.e. each grid point)
t2m.scaled <- apply(t2m.vec, 2, scale, scale=FALSE, center=TRUE) 

rm(t2m.en)
#  LOOP OVER THE VARIABLES TO PLOT

    # Conduct the SOM analysis
var.som <- som(t2m.scaled, grid = somgrid(2,2, "rectangular"))#, keep.data=TRUE))

var.vecc = mat.or.vec(Nlat*Nlon, Nsom)

#populate var.vecc with the SOM output maps

for (i in 1:Nsom) {
        print(i)
        ## THIS IS WHERE THE ERROR IS
          var.vecc[,i] <- var.som$codes[i,]
        ## The Error Message is: 
        ## Error in var.som$codes[i, ] : incorrect number of dimensions  
}
#var.som$codes[1]
# Plot data from var.vecc on a map  

Solution

  • Try: var.vecc[,i]<-var.som$codes[[1]][i,]