2

My overall goal is to classify an image using random forest. The dataframe contains training data; where 'landcover' contains the classes 0, 1 and 2. I am trying to reduce the number of classes by changing all the 2's to 0's, using the dplyr transmute() method. The whole code works except for the critical last line-- GP_training1 <- transmute(GP_data$landcover, landcover = ifelse(landcover==1,1,0)). When I run this I get the error: no applicable method for 'mutate_' applied to an object of class "c('integer', 'numeric')". Any ideas why this may be? Relevant code is pasted below.

#import raster and shapefile; each color band is overlayed on top of 
eachother w coordinate system underneath
GP_1_4 <- brick("Downloads/Landsat Mosaics/GP_1-4.tif")
names(GP_1_4) <- c("Red","Green","SWIR")
GP_1_4 <- subset(GP_1_4, order(c(3, 2, 1)))
plotRGB(GP_1_4,stretch="lin")

#import shapefile of training points
GP_training < readOGR("Downloads/GP_716_shapefile3/GP_716_training3.shp", layer="GP_716_training3")
list.files("GP_716_shapefile3")

#extract points from raster 
dataSet <- as.data.frame(extract(GP_1_4, GP_training))

#and put in same dataframe as training data
GP_training$data = data.frame(GP_training$data, dataSet[match(rownames(GP_training$data), rownames(dataSet)),])
GP_training$data = GP_training$data[complete.cases(GP_training$data),]

#make a new dataframe, identical to GP_training, except the 2's are changed to 0's
GP_training1 <- GP_training
GP_data <- GP_training1$data
GP_training1 <- transmute(GP_data$landcover, landcover = ifelse(landcover==1,1,0))

NEW EDIT: Using the function isS4(), I've discovered that GP_training is an S4 object. Meanwhile, R documentation says that "All main verbs are S3 generics" for transmute(). I'm not very familiar with S3 and S4, but could this be where the error is happening?

karc11
  • 115
  • 1
  • 2
  • 6
  • In your 5th last line `GP_training$data = GP_training$data[complete.cases(GP_training$data),]` you are assigning a vector that could be a different length. This would introduce `NA` values that will cause `ifelse` problems. – mrjoh3 Sep 18 '18 at 21:25
  • Also can you provide a shorter or dummy dataset for your example. This will make it more reproducible for others. – mrjoh3 Sep 18 '18 at 21:26
  • Thanks for the tip! I'm pretty new to R so I'm not sure what a good way to get publicly available/short/easy dataset is-- any advice? – karc11 Sep 18 '18 at 21:38
  • See [How to make a great R reproducible example?](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) – Calum You Sep 18 '18 at 22:00
  • `dplyr::transmute` can only be used on a data.frame, but you gave it a vector: `GP_data$landcover`. You should give it the data.frame `GP_data` and let it work with that: `transmute(GP_data, landcover = ifelse(...` – divibisan Sep 18 '18 at 23:00
  • Thank you so much @divibisan, it worked! – karc11 Sep 18 '18 at 23:12

1 Answers1

2

dplyr::transmute can only be used on a data.frame, but you gave it a vector: GP_data$landcover. You should give it the data.frame and let it work with that.

This is different from the code you're using, but it does what your comment says:

library(dplyr)

GP_training1 <- GP_training %>%                   # Create a new data.frame from GP_training
    mutate(landcover = ifelse(landcover==1,1,0))  # Change the value of `landcover` to 
                                                  #  either 1 or 0 based on its current value

Use mutate instead of transmute because mutate adds/changes variables while exiting ones. transmute keeps only the variables you create

divibisan
  • 11,659
  • 11
  • 40
  • 58