3

There seems to be variations to this question, but none seem to address the situation of being in a loop AND naming and output file. How I thought this might work:

for(j in 1:3) {
    for(k in 1:17){
       extract_[j]km <- extract(RasterStack, SpatialPolygonsDataFrame_[j]km, layer=[k], nl=1, df=TRUE)
    }
}

The extract function is from the raster package. I have already created a series of RasterStacks and SpatialPolygons and I want to pass these to a function ("extract") that has several parameters, some of which I wish to manipulate through the loop, and label the output accordingly. This is a breeze in BASH, but I can't figure this out in R.

Ultimately, I'd like to pass strings as well, but another post seems to show the way there.

EDIT: I originally posted the above function as being a single dataframe, when in fact, they are specified objects from the raster package (which are ultimately dataframes).

Community
  • 1
  • 1
Prophet60091
  • 589
  • 9
  • 23
  • 2
    You can do this using `assign` but it isn't advisable. Instead, the R way would be to assign each as an element of a named list. Between `get` and `assign` there is plenty of rope to hang yourself with, but would suggest rethinking your approach and using some of the list tools that R has instead. – Justin Dec 16 '12 at 00:29
  • Your update is problematic. It would return extract[1]km for layer=17, extract[2]km for layer=17 and extract[3]km for layer=17. – Brandon Bertelsen Dec 16 '12 at 22:17
  • For posterity, answer by author of the function can be found here: http://r-sig-geo.2731867.n2.nabble.com/raster-How-to-loop-extract-function-td7581978.html – Roman Luštrik Dec 17 '12 at 09:48
  • @RomanLuštrik - this works...should it be included as an answer? – Prophet60091 Dec 17 '12 at 13:13
  • It would be nice if Robert could drop by and post it as an answer, for completeness sake. :) – Roman Luštrik Dec 17 '12 at 13:37

1 Answers1

4

As Justin points out, working with a list is more inline with R's structure than messing up the workspace with lots of named variables. It quickly becomes challenging to work when you have a lot of objects in the workspace to "know" what's next.

Your way:

for(j in 1:3) { 
assign(
   paste("extract",j,"km",sep=""), # or paste0 to avoid need for sep=""
   function(
            get(
                paste("data",j,"km",sep="")
               )
           )
      )
}

Personally, I prefer working with lists, so below, I convert your data objects to a list and show you how to run a function on all elements of that list. Working in this way usually relegates the need to use strings in the "get" and "assign" fashion.

# just converting your variables to a list    
data.list <- mget(grep("data",ls(),value=TRUE),envir=.GlobalEnv) 

# then output results
result.list <- lapply(data.list,your_function) 
Brandon Bertelsen
  • 43,807
  • 34
  • 160
  • 255
  • I ran into a slight issue with `data.list <- mget(grep("data",ls(),value=TRUE),envir=.GlobalEnv)`. grep() seems to match anything that contains the string "data", so if I have an object named data.fnc() in the workspace, it will also retrieve that. Do you happen to know any workaround? – Alex Dec 16 '12 at 05:14
  • Its' generally bad practice to name an object 'data', because this is a reserved word in base R. Not being able to see your workspace I can't "see" what you're trying to do. However, perhaps you could try: `grep("data[0-9*]",ls(),value=TRUE)` – Brandon Bertelsen Dec 16 '12 at 08:58
  • I think I see how the list approach might work for the toy example I gave, but my function is actually a bit more complex. I've updated the original post to reflect the function in more detail. Hopefully, there's a more straightforward way of passing strings/numbers to a function. – Prophet60091 Dec 16 '12 at 21:05
  • The straightforward way to call or create objects by string is by using a combination of paste(), get() or assign(). As I don't know what extract() returns, I can't assist much further unless you provide us with example data and an example of what you would expect returned. – Brandon Bertelsen Dec 16 '12 at 22:19
  • 1
    @BrandonBertelsen - +1 for the help, but the posted link above works. My bad for not framing the question correctly to begin with. – Prophet60091 Dec 17 '12 at 13:14