0

My apologies. This is my first time using Stackoverflow, so I'm not used to posting questions. Here's what I'm coding

library(raster)
library(landscapemetrics)
library(landscapetools)

# Add raster data for 2000
hex1_2000<-raster('2000_hex1.tif')
hex2_2000<-raster('2000_hex2.tif')
hex3_2000<-raster('2000_hex3.tif')
hex4_2000<-raster('2000_hex4.tif')
...
hex23_2000<-('2000_hex4.tif')

# Add raster data for 2010
hex1_2010<-raster('2010_hex1.tif')
hex2_2010<-raster('2010_hex2.tif')
hex3_2010<-raster('2010_hex3.tif')
hex4_2010<-raster('2010_hex4.tif')
...
hex23_2010<-('2000_hex4.tif')

#Create data frame as table

hex1 = data.frame(
  lc00 = values(hex1_2000),
  lc10 = values(hex1_2010))
hex2 = data.frame(
  lc00 = values(hex2_2000),
  lc10 = values(hex2_2010))
hex3 = data.frame(
  lc00 = values(hex3_2000),
  lc10 = values(hex3_2010))
hex4 = data.frame(
  lc00 = values(hex4_2000),
  lc10 = values(hex4_2010))
...
hex23 = data.frame(
  lc00 = values(hex23_2000),
  lc10 = values(hex23_2010))
...

hex1 = table(hex1[,c('lc00','lc10')])
hex2 = table(hex2[,c('lc00','lc10')])
hex3 = table(hex3[,c('lc00','lc10')])
hex4 = table(hex4[,c('lc00','lc10')])
...
hex23 = table(hex23[,c('lc00','lc10')])

#Define crosstabulation matrix

Hex1_Trans = as.matrix(hex1 / rowSums(hex1))
write.csv(Hex1_Trans, 'hex1Trans.csv')

Hex2_Trans = as.matrix(hex2 / rowSums(hex2))
write.csv(Hex2_Trans, 'hex2Trans.csv')

Hex3_Trans = as.matrix(hex3 / rowSums(hex3))
write.csv(Hex3_Trans, 'hex3Trans.csv')

Hex4_Trans = as.matrix(hex2 / rowSums(hex4))
write.csv(Hex4_Trans, 'hex2Trans.csv')

...
Hex23_Trans = as.matrix(hex23 / rowSums(hex23))
write.csv(Hex23_Trans, 'hex23Trans.csv')

As you can see, there are innumerous instances where I'm repeating the same process. I would be delighted to know how I can make this code simpler and more elegant. My coding is always like this, and I find this obviously highly inefficient. Thank you everyone for your help.

perrier
  • 3
  • 3
  • 2
    I do not really understand how your heading is connected to your question. Additionally, please provide a [reproducible minimal example](https://stackoverflow.com/q/5963269/8107362). Especially, provide some sample data, e.g. with `dput()`. – mnist Nov 15 '19 at 22:55
  • 1
    I have a hard time imagining how the `hexi` are related to each other. Please provide a [mcve]. See [How to make a great R reproducible example?](https://stackoverflow.com/q/5963269/4996248) for what this would mean in R. – John Coleman Nov 15 '19 at 22:57
  • Thank you very much. I hope the above makes my question more explicit. – perrier Nov 15 '19 at 23:33

3 Answers3

1

Here is an incomplete draft illustrating how to use Map to iterate simultaneously through the 2000 and 2010 data.

fn_y2000 <- c("2000_hex1.tif", "2000_hex2.tif", "2000_hex3.tif")
fn_y2010 <- c("2010_hex1.tif", "2010_hex2.tif", "2010_hex3.tif")
lst <- Map(
    function(x1, x2) {
        hex1 <- raster(x1)
        hex2 <- raster(x2)
        tbl <- table(values(hex1), values(hex2))
        #... Normalise and write output 
    },
    fn_y2000, fn_y2010)

The return object is a list.

Maurits Evers
  • 49,617
  • 4
  • 47
  • 68
  • awesome! Thank you!! This makes sense. – perrier Nov 15 '19 at 23:58
  • You're very welcome @perrier. These `Map`/`mapply`/`lapply`/`*apply` functions are very useful for iterating through one (or multiple) `list`-like objects. They're really just an optimised loop in disguise. – Maurits Evers Nov 16 '19 at 00:04
  • 1
    This is truly awesome. I was getting very frustrated with my lengthy (and highly inefficient) repetitions. This changes a lot my way of coding from now on. I'm so glad I tried out posting this on stackoverflow. Have a great weekend. – perrier Nov 16 '19 at 00:11
0

Maybe something like the following will do what the question asks for.
It is a repeated use of lapply to read in the data files and table the required columns.

hexnames <- list.files(pattern = "2000_hex\\d+\\.tif")
hex_list <- lapply(hexnames, raster)
names(hex_list) <- paste0("hex", seq_along(hex_list), "_2000")
hex_table <- lapply(hex_list, function(X) table(X[, c('lc00','lc10')]))
Rui Barradas
  • 70,273
  • 8
  • 34
  • 66
  • Thank you. Yes, this seems to allow me to import all the tif files! However it does return an error: Error in X[, c("lc00", "lc10")] : object of type 'S4' is not subsettable – perrier Nov 15 '19 at 23:32
-1

Very simple solution, try assign(). This code is from Data Camp's documentation page.

for(i in 1:6) { 
  #-- Create objects 'r.1', 'r.2', ... 'r.6' -- 
  nam <- paste("r", i, sep = ".") 
  assign(nam, 1:i) 
} 

ls(pattern = "^r..$") 

Here is the link to the page. Look at the 'Examples' section. rdocumentation.org/packages/base/versions/3.6.1/topics/assign

DPek
  • 180
  • 2
  • 15
  • 1
    Awesome. Thanks! – perrier Nov 15 '19 at 23:04
  • 1
    Worth adding that programmatically generating objects via `assign` isn't really a best practice. It would usually be better to store these in a `list()` – Mako212 Nov 15 '19 at 23:06
  • 2
    No don't do this! This is not the R way. Beware the dangers of using [`assign`](https://stackoverflow.com/questions/17559390/why-is-using-assign-bad). – Maurits Evers Nov 15 '19 at 23:06
  • Thank you @MauritsEvers, I never knew this! – DPek Nov 15 '19 at 23:08
  • Thank you. I didn't figure it out either. How would I solve it with the example above? thanks so much. – perrier Nov 15 '19 at 23:17
  • @perrier I would recommend a `list` approach as suggested by @Mako212. So to start with, something along the lines of `fn <- c("2000_hex1.tif", "2000_hex2.tif", "2000_hex3.tif"); lst <- lapply(fn, raster)` to read the TIFs into a `list`. – Maurits Evers Nov 15 '19 at 23:44