Question

I have data on land use over time and am trying to write a logical function that returns whether or not an observation (which is a small block of land) has CHANGED from grassland to cropland and has STAYED in cropland. Below is my small sample from my dataframe.

crop2 <- read.table(text="
OBS         2003      2004      2005      2006      2007      2008      changes
494136 Grassland Grassland Grassland Developed Cropland  Grassland      2
825726 Developed Developed Developed Grassland Grassland Grassland      1
500019    Forest    Forest    Forest    Forest    Forest Grassland      1
587587  Cropland  Cropland  Cropland  Cropland  Cropland  Cropland      0
524302 Grassland Grassland  Cropland  Cropland  Cropland  Cropland      1
158075  Cropland  Cropland  Cropland  Cropland  Cropland  Cropland      0
",header=TRUE,check.names=FALSE)

In this sample of data, the function would return only the second to last observation with a true. I have tried using various functions and if-statements but cannot get the coding correct (partially because the transition from cropland to grassland could occur in any year. I was able to write this function to find if changes do occur (it is the changes variable) but need to extract more information than just whether or not a change occurs: length(unique(as.character(crop2[x,])))

My dataframe is named crop2 and each column is named with the year. The variables are factors with 5 levels. Thanks for you help.

Was it helpful?

Solution

Using rle:

apply(
  crop2[2:7],
  1,
  function(x) all(tail(rle(x)$values,2) == c("Grassland","Cropland")) 
)
#[1] FALSE FALSE FALSE FALSE  TRUE FALSE

A function is apply-ed across each row (MARGIN=1) of your yearly data as defined by the subset crop2[2:7].

rle(x)$values returns the order of the changes in land use, e.g. row 5 is:

#       2004        2008 
#"Grassland"  "Cropland"

Wrapping this in tail(...,2) just gives the change between the last 2 uses, which in this instance is just the same data again:

#       2004        2008 
#"Grassland"  "Cropland"

The all(... = c("Grassland","Cropland")) bit just tests whether the land use finished as "Cropland" after coming directly from "Grassland", which in this instance is TRUE

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top