1

In R, I have spatial coordinate data for a grid of data with x and y coordinates in two columns from 0-100.

I would like to loop over both x and y columns to identify specific ranges on a 10x10 subgrid, then output a new subregion ID in another column

For example, I would like select a range of values that match both those in the x coordinates column (e.g. 0-9) and the y coordinates (e.g. 20-29) to produce an output in a new column called SubRegion. Of course it would then iterate through to match all of the potential ~100 subregions. (In reality my data are a bit more complicated but this is a simplified explanation)

I've added a new column to the dataframe and written a for loop that is successful across one column but unsuccessful with 2 columns of data.

The following code is unsuccessful in producing a result on 2 columns

df$SubRegion <- NA # added a new sub region column to df

for (i in 1:nrow(df)){ 
  if (df$yCord[i] > 0.00 & df$yCord < 9.99 & df$xCord > 0.00 & df$xCord < 9.99){df$SubRegion [i]=1}

  if (df$yCord[i] > 10.00 & df$yCord < 19.99 & df$xCord > 0.00 & df$xCord < 9.99){df$SubRegion [i]=2}

  if (df$yCord[i] > 20.00 & df$yCord < 29.99 & df$xCord > 0.00 & df$xCord < 9.99){df$SubRegion [i]=3}

  }

If I simplify the code to select a range on one column, I can get it to work:

for (i in 1:nrow(df)){ 
  if (df$yCord[i] > 0.00 & df$yCord < 9.99{df$SubRegion [i]=1}

  if (df$yCord[i] > 10.00 & df$yCord < 19.99{df$SubRegion [i]=2}

  if (df$yCord[i] > 20.00 & df$yCord < 29.99{df$SubRegion [i]=3}

I would like an output that looks like this:

yCord   | xCord  | SubRegion
1       |3       |1
1       |9       |1
10      |3       |2
22      |5       |3

Instead I'm not getting any results, just NA

  • Please provide [input](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) with a `dput` sample of few rows. Loop seems to be checking against row items by `i` (`df$yCord[i]`) and all values of column with no `i` (`df$yCord`). Might be a typo? There may be ways without any loop using `cut` or `ifelse`. – Parfait Jul 13 '19 at 16:12
  • Thanks @Parfait, it was a silly [i] typo. Thanks for the quick response... – ForestEcologist Jul 13 '19 at 16:31

1 Answers1

0

Consider nested ifelse, a vectorized solution avoiding iteratively traversing rows in loop. Parentheses added for readability (in the Python Pandas-esque style but not required in R). Also, with() is a context manager to avoid qualifying df$ for each column.

df$SubRegion <- with(df, 
      ifelse((yCord > 0.00 & yCord < 9.99) & (xCord > 0.00 & xCord < 9.99), 1,
             ifelse((yCord > 10.00 & yCord < 19.99) & (xCord > 0.00 & xCord < 9.99), 2,
                    ifelse((yCord > 20.00 & yCord < 29.99) & (xCord > 0.00 & xCord < 9.99), 3, NA)
                   )
             )
)

Rextester demo (with reproducible, random data)

Parfait
  • 104,375
  • 17
  • 94
  • 125