0

I have raster images and I want to apply a function that will give a value based of adjacent cells values. In a 3x3 window centered in that cell I want to give a cell a value between 0 and 8/8(=1) depending on how many cells (from the other 8 cells in that window). For example if 5 other cells have different values than the center cell, the function must assign 5/8 in that cell. I am trying to do that using focal from raster package.

Firstly, I wrote a function that process a 3x3 window:

    mix<-function(a, na.rm=TRUE){
  v==0
  b=a[2:2]
  if (!(a[1:1]=b)) {
    if (!is.na(a[1:1])){v=v+1}else v=v
  }
   if(!(a[1:2]=b)){if (!is.na(a[1:2])){v=v+1}else v=v}
    if(!(a[1:3]=b)){if (!is.na(a[1:3])){v=v+1}else v=v}
     if(!(a[2:1]=b)){if (!is.na(a[2:1])){v=v+1}else v=v}
      if(!(a[2:3]=b)){if (!is.na(a[2:3])){v=v+1}else v=v}
       if(!(a[3:1]=b)){if (!is.na(a[3:1])){v=v+1}else v=v}
        if(!(a[3:2]=b)){if (!is.na(a[3:2])){v=v+1}else v=v}
         if(!(a[3:1]=b)){if (!is.na(a[3:3])){v=v+1}else v=v}
  v
}

Then I tried to use focal like this:

r2<-focal(r, w=matrix(1,3,3), fun=mix(w))

but: "Error in mix(w) : object 'v' not found"

I think that I am missing something and maybe the method is not correct.

Any help will be appreciated.

Thanks In advance John

Argalatyr
  • 4,639
  • 3
  • 36
  • 62
  • 1
    maybe assigning `v==0` should be `v <- 0` and comparison with `==` – bergant Apr 04 '15 at 18:46
  • And perhaps the colon operator in R does not match your expectations. See `?":"` – bergant Apr 04 '15 at 18:56
  • Thanks. v<-o solve the error. Al thought, I still have a problem. In line r2<-focal(r, w=matrix(1,3,3), fun=mix(w)) , w is not recognized in mix(w). I expect something like this, cause you actualy put a function and the input is not w, but all the numbers from the 3x3 window. I can't figure how I will refer to this as a matrix. – user3052581 Apr 04 '15 at 20:15
  • I made some progress, I' ll write in an answer, but is not a full answer – user3052581 Apr 05 '15 at 06:43

3 Answers3

1

That is a bad function, hard to read, and inefficient. Bergant showed a much better alternative, here is another variation.

mix2 <- function(a, ...){
   i <- a[5] != a
   mean(i[-5], na.rm=TRUE)
}
Robert Hijmans
  • 40,301
  • 4
  • 55
  • 63
0

I finally solve my problem I correct the mix function like this:

mix<-function(a, na.rm=TRUE){
  v<-0
  b=a[5]
  if (!(a[1]==b)) {if (!(a[1]==0)){v=v+1}else v=v}
   if(!(a[2]==b)){if (!(a[2]==0)){v=v+1}else v=v}
    if(!(a[3]==b)){if (!(a[3]==0)){v=v+1}else v=v}
     if(!(a[4]==b)){if (!(a[4])==0){v=v+1}else v=v}
      if(!(a[6]==b)){if (!(a[6])==0){v=v+1}else v=v}
       if(!(a[7]==b)){if (!(a[7])==0){v=v+1}else v=v}
        if(!(a[8]==b)){if (!(a[8])==0){v=v+1}else v=v}
         if(!(a[9]==b)){if (!(a[9])==0){v=v+1}else v=v}         
  v/8
}

Now the mix function works fine. Making examples with focal seems that focal use a vector of the numbers in the applied window. So it should work fine. I also tested in an a made up 10x10 raster and works fine

I mark it as answered.

Have a nice day

0

In R you can execute basic operations on vectors:

mix2<-function(a, na.rm = TRUE){
  b <- a[5]
  a <- a[-5]
  mean(ifelse(a != b & a != 0, 1, 0), na.rm = na.rm)
}
bergant
  • 7,122
  • 1
  • 20
  • 24
  • You don't really need the `ifelse` here since TRUE gets converted to 1 and FALSE to 0 if you use them in things like sum, mean, ... so you could just do `mean(a !=b & a != 0, na.rm = na.rm)` – Dason Apr 06 '15 at 16:03