mahagadorn / r-world-mahagadorn

r-world-mahagadorn created by GitHub Classroom
0 stars 0 forks source link

Tackling Plants together!!! #4

Closed mahagadorn closed 7 years ago

mahagadorn commented 7 years ago

@MaggiK @jocelyn-cuthbert

We are working on tackling these errors together. Multiple minds are greater that one. Below is the code we have come up with...


plant.timestep <- function(plants, info){
  #define survivor function
  survive <- function(plant, info){
    if(is.na(plant))     #if it isnt a species I want you to return what is already in the contents of the cell
      return(NA)
    if (plant=='')
      return('')
    if(runif(1) <= info$survive[name])   #your value is greater than or equal to your survival probability then you win yay!
      return(name)
    if(runif(1) >= info$survive[name])   #if the random number is greater that our survival probablity the return a blank space
      return('')    #this makes sense because if it dies it's no longer there...there is nothing in this cell
  }
  #looping through the plant matrix
  for(i in 1:nrow(plants)){
    for(j in 1:ncol(plants)){
      new.plant.matrix <- survive(plants[i,j], info)
      return(new.plant.matrix)
    }
  }
}

#here is the run.ecosystem

run.plant.ecosystem <- function(terrain, num.timesteps, info){
  terrain <- terrain
  info <- info
  #Make the array
  plants <- array("", dim=c(dim(terrain), num.timesteps + 1))
  for(i in seq_len(dim(plants)[3]))
    #seq_len(y) or in our case (seq_len(dim(plants)) is creating a sequence up dimensions of plants array
    plants[,,k][is.na(terrain)] <- NA
      for(k in 1:dim(plants)[3]){
        print(i)
        plants[i,j,k] <- plant.timestep(plants[i,j,k], info)
  }
}

run.plant.ecosystem(Test.Terrain, 2, info)

####ERROR: Error in plants[, , k][is.na(terrain)] <- NA : object 'k' not found

Hey guys use this to kind of bounce ideas of each other.

Best, Mal

MaggiK commented 7 years ago

Maybe progress??

You can change the for statement near the end to

for(k in seq_len(dim(plants)[3])) plants[,,k][is.na(terrain)] <- NA plants[,,k]<- plant.timestep(plants[,,k], info)

At this point I receive no errors but it also returns with all blank cells or NA where appropriate. I suppose this is because we have if (plant=='') return('') in there. So maybe we have to start with a plant matrix to see change?

mahagadorn commented 7 years ago

So I tinkered with that and I am returning the same thing, EXCEPT my last timestep matrix is missing the NA's where they should be.

So it seems like the issue is that we aren't actually tethering the plants??? I mean there should be species names present in the array.

So I made one adjustment to see what is happening....not sure if you deleted this part too...


run.plant.ecosystem <- function(terrain, num.timesteps, info){
  terrain <- terrain
  info <- info
  #Make the array
  plants <- array("", dim=c(dim(terrain), num.timesteps + 1))
  for(k in seq_len(dim(plants)[3]))
    #seq_len(y) or in our case (seq_len(dim(plants)) is creating a sequence up dimensions of plants array
    plants[,,k][is.na(terrain)] <- NA
        plants[,,k] <- plant.timestep(plants[,,k], info)
}

run.plant.ecosystem(Test.Terrain, 3, info)

So I removed the the `return(plants)at the end and the return I got was[1] 1 [1] 5. Did you keep thereturn(plants)statement at the end of yours? What should be being returned from the plant.timestep function isreturn(new.plant.matrix)`` , however those numbers don't make sense to be what is being returned. When looking back I kept two print statements in my timestep function to see exactly where things are leaving off... see code below:


plant.timestep <- function(plants, info){
  #define survivor function
  survive <- function(plant, info){
    if(is.na(plant))     #if it isnt a species I want you to return what is already in the contents of the cell
      return(NA)
    if (plant=='')
      return('')
    if(runif(1) <= info$survive[name])   #your value is greater than or equal to your survival probability then you win yay!
      return(name)
    if(runif(1) >= info$survive[name])   #if the random number is greater that our survival probablity the return a blank space
      return('')    #this makes sense because if it dies it's no longer there...there is nothing in this cell
  }
  #looping through the plant matrix
  for(i in 1:nrow(plants)){
    print(i)
    for(j in ncol(plants)){
      print(j)
      new.plant.matrix <- survive(plants[i,j], info)
      return(new.plant.matrix)
    }
  }
}

...Therefore, those return values are the i and j values where the functions "left off". To me this suggest that there is something perhaps wrong with the i part of the timestep function. It shouldn't be stoping at i=1 it should be i=5 since there are five rows. @MaggiK any other ideas? I am going to look at it more after a short break (because I am feeling a bit aggravated, which resulted in my throwing Lady Quacks [my duck] at the wall at a very high velocity). @willpearse, is the type of conversation/collaboration acceptable?

MaggiK commented 7 years ago

hmmm. OK. I feel like I have stared at this so much and tinkered with so many different parts and haven't got anywhere. The for statement should work. I think you are right about it not tethering the plants.

I have been messing with this some more but I think we could use some insight or guidance.

MaggiK commented 7 years ago

I guess we do seed the first array with plants. But I still can't get it to work and transfer plants to the next timestep.

jocelyn-cuthbert commented 7 years ago

Yeah I had thought there were plants in the array - but also have we "seeded" the plants in the terrain matrix? Do we need to assign plant a,b and c a random location for timestep one and then have it store and build on that location through the timesteps? Looking through I'm wondering if we set up the array, and set up the matrix, but never really connected them.

mahagadorn commented 7 years ago

Hey ladies,

So I am doing this from my phone (aka not sure if it will work). Look at my most recent push, @AlexRego and I made a wee bit of progress last night. We added in a part for randomly seeding the first plant matrix. Mine won't transfer to the next time step, so I think there is still an issue with that function. I'm going to work more through it today.

MaggiK commented 7 years ago

Ya, your way is way more eloquent than the way I was seeding plants. But I still can't get them to move to the next timestep. I have been playing with the k-1 but now I am back to the incorrect dimensions error. I see Alex added k in his survive function. My understanding was that we don't do this? k is only in timestep.

AlexRego commented 7 years ago

Maggie, not sure where you're seeing k in my survive function. If you mean when I input eco[i,j,k] into survive during my timestep function, it's so that survive looks at the correct cell and timestep.

MaggiK commented 7 years ago

Ya sorry. I meant the timestep function. I guess that makes sense. I still can't get it to step through time. Alex- does yours step through the timesteps?

AlexRego commented 7 years ago

Sure as heck does.

MaggiK commented 7 years ago

nice

mahagadorn commented 7 years ago

@AlexRego

Hey Alex,

So the way I have mine written is

plant.timestep <- function(plants, info){
  #define survivor function
  survive <- function(plant, info){
    if(is.na(plant))     #if it isnt a species I want you to return what is already in the contents of the cell
      return(NA)
    if(plant=='')
      return('')
    if(runif(1) <= info$survive[name])   #your value is greater than or equal to your survival probability then you win yay!
      return(name)
    if(runif(1) >= info$survive[name])   #if the random number is greater that our survival probablity the return a blank space
      return('')    #this makes sense because if it dies it's no longer there...there is nothing in this cell
  }
  #looping through the plant matrix
  for(k in 1:(nrow(plants)^2)[3]-1){
    for(i in 1:(nrow(plants)^2)[1]){
      for(j in 1:(nrow(plants)^2)[2]){
      plants[i,j,k] <- survive(plants[i,j,k], info)
      return(plants)
      }
    }
  }
}

I when I did mine I didn't use the dim() function I just squared the number of rows (since that's taking the dimensions of the matrix). I am getting an error message, so clearly it's not doing what I think it should. Any particular reason why you use dim() ? I assume it's the more efficient way of doing things...Is it because your are trying to calling the 3rd dimension?

mahagadorn commented 7 years ago

Hey @MaggiK ,

I did figure out something...maybe you are experiencing the same thing.

So I have generated and seeded my first array. I think my survive function has an issue.


survive <- function(cell, info){
    if(is.na(cell))     #if it isnt a species I want you to return what is already in the contents of the cell
      return(NA)
    if(cell=='')
      return('')
    if(runif(1) <= info$survive[name])   #your value is greater than or equal to your survival probability then you win yay!
      return(name)
    if(runif(1) >= info$survive[name])   #if the random number is greater that our survival probablity the return a blank space
      return('')    #this makes sense because if it dies it's no longer there...there is nothing in this cell
  }

When the line if(runif(1) <= info$survive[name]) is returning this:

> survive(plants[3,1,1], info) [1] "M. sativa" "L. perenne" "T. repens"

When I feed it a cell that I know has a specific plant name in it. So it is returning all plant names instead of the specific plant name that is located in that cell. I changed it to just cell and am still getting all species names when the species survives. AHHHHHH. Any insight?

MaggiK commented 7 years ago

I have no insights. Rubber duck has gone flying out the window. I think my survive function is struggling as well. I can't escape the error Error in if (is.na(cell)) { : argument is of length zero

I tried changing my survive function around to look a little more like Alex's thinking the else statement may be necessary. But no, I still get the error.

mahagadorn commented 7 years ago

My survive works as...


  survive <- function(cell, info){
    if(is.na(cell))     #if it isnt a species I want you to return what is already in the contents of the cell
      return(NA)
    if(cell=='')
      return('')
    if(runif(1) <= info$survive[cell])   #your value is greater than or equal to your survival probability then you win yay!
      return(cell)
    if(runif(1) >= info$survive[cell])   #if the random number is greater that our survival probablity the return a blank space
      return('')    #this makes sense because if it dies it's no longer there...there is nothing in this cell
  }

survive(plants[3,1,1], info)

I had to specify the different return!!! I kept it as return(plants) so no wonder its returning all three. Does that help yours?

MaggiK commented 7 years ago

Maybe? Now I am back to a dimension error.

MaggiK commented 7 years ago

yes. That works. I can manually use the previous survival to adjust the next level of survival! Now the loop...

mahagadorn commented 7 years ago

What send me a visual of what you meant in the last one haha... I need to see the code to see what you are talking about! HAHA

I keep getting the error

Error in 1:(dim(plants)[3] - 1) : NA/NaN argument when trying to run my ecosystem function

MaggiK commented 7 years ago

If I manually seed my first array, then run: plants[3,2,2]<-survive(plants[3,2,1], info) plants[,,2]

survive <- function(cell, info){ if(is.na(cell)) return(NA) if (cell=='') return('') if(runif(1) <= info$survive[cell]) return(cell) if(runif(1) >= info$survive[cell]) return('') }

It fills in the second dimension. But if I try to plug it into my ecosystem function like you did I get either that same error or the argument of length zero error. So now I know my loop doesn't work.

mahagadorn commented 7 years ago

Ohhhh, I see! hmm....your are making more progress than me haha. I can't get to the second because i just keep getting the error! My poor duck, he's a pessimistic duck.

MaggiK commented 7 years ago

Breakthrough!

Ok. Here is everything because I need to figure out what order I did stuff in.

terrain matrix

terrain<- mat_func(3,3) terrain[1,1]<-NA terrain[1,2]<-2.2 terrain[1,3]<-3.4 terrain[2,1]<-.6 terrain[2,2]<-.5 terrain[2,3]<-.3 terrain[3,3]<-NA terrain[3,2]<-4.4 terrain[3,1]<-1.8 terrain

c_mat<- mat_func(3,3) c_mat[1,1]<-.5 c_mat[1,2]<-.2 c_mat[1,3]<-.4 c_mat[2,1]<-.6 c_mat[2,2]<-.5 c_mat[2,3]<-.3 c_mat[3,3]<-.5 c_mat[3,2]<-.4 c_mat[3,1]<-.8 c_mat

repro

repr<- c(.3,.6,.8) repr

survival

surv<-c(.2,.5,.6)

names

names<-c("a","b","c") rownames(c_mat)<-names colnames(c_mat)<-names

checking life history parameters

setup.plants <- function(repro, survive, comp.mat, name=NULL){ if(is.null(name)) name <- letters[seq_along(repro)] if(length(repro) != length(survive)) stop("Reproduction and survival parameters needed for all species") if(length(repro) != ncol(comp.mat)) stop("Reproduction and competition matrix needed for all species") if(ncol(comp.mat) != nrow(comp.mat)) stop("number of col needs to match number of rows") repro <- setNames(repro, name) survive<- setNames(survive, name) return(list(repro=repro, survive=survive, comp.mat=comp.mat, names=names)) } info<-setup.plants(repr, surv, c_mat)

create the input data

plants <- array("", dim=c(dim(terrain),timesteps+1)) plants[1,1,1]<- "a" plants[1,2,1]<-"b" plants[1,3,1]<-"" plants[2,1,1]<-"a" plants[2,2,1]<-"" plants[2,3,1]<-"b" plants[3,3,1]<-"" plants[3,2,1]<-"c" plants[3,1,1]<-"a"

for(k in seq_len(dim(plants)[3])) plants[,,k][is.na(terrain)] <- NA

plant.timestep

plant.timestep <- function(plants, info){ survive <- function(cell, info){ if(is.na(cell)) return(NA) if (cell=='') return('') if(runif(1) <= info$survive[cell]) return(cell) if(runif(1) >= info$survive[cell]) return('') }

the timestep: k dimensions, i rows, and j columns

for (k in seq(dim(plants)[3]-1)){ for (i in 1:nrow(plants)){ for (j in 1:ncol(plants)){ plants[i,j,(k+1)]<- survive(plants[i,j,k], info) } } } return(plants) }

run plant.timestep

plant.timestep(plants, info)

And it appears to work! Minor detail is that I am running plant.timestep and not run.plant.ecosystem function. But hey, it fu**in works.

MaggiK commented 7 years ago

it works about 50% of the time. The rest of the time I get an error number of items to replace is not a multiple of replacement length

mahagadorn commented 7 years ago

THAT'S THE ERROR I KEEP GETTING! I'm not using the same looping format as you but I get the same error every time.

I run my plant.timestep function and it seems to work. It prints out all my i,j,k values and they seem to be the right combinations.

Not sure what the error means.

willpearse commented 7 years ago

Your error message means that you are trying to replace something with something that isn't of the same length as its replacement.

Take a look at the value of the thing you are trying to store (survive(plants[i, j, k], info)) and comparing it with the thing you're trying to store it into (plants[i, j, k]). I think if you look at the return statement on your function it will make more sense.