0

In R, I have a shapefile with polygons. I subsetted by a secondary ID. Now, I want to sum up all area values of the subset. These are the are values of the subset:

shapefile.subset$area
## 7767 1597 947  626  552 
## 1424 Levels: 0 1 10060 10070 10124 1013 1017 10175 1019 10191 1022 102361 
## 10237 10298 1030 10324 10327 1035 1039 10403 10405 1042 1044 104453 104533 
## 10508 1051 10562 ... 9982

Summing returns the following:

sum(shapefile.subset$area)
## Error in Summary.factor(c(1247L, 275L, 1388L, 1101L, 1025L), na.rm = FALSE) : 
  ‘sum’ not meaningful for factors

So I tried to convert into numeric

as.numeric(shapefile.subset$area)

which returns

1247  275 1388 1101 1025

Thus five values that do not have anything in common with the original values. Note, that these also appear in the error message of sum(shapefile.subset$area). I am really stuck here - how can I avoid this strange behaviour?

2 Answers 2

1

This behavior is not at all strange, the values being returned after coercion are the position in the factor and not the value in the vector. In a numeric vector that is, for some reason a factor, you coerce to a character then numeric ie, as.numeric(as.character(x))

Let's create a numeric vector of [0,1,5] and coerce to a factor.

class( x <- c(0,1,0,1,5,1) )
class( x <- as.factor(x) )

When we look a the factor levels you will see that the value "5" is in the third position of the factor. If we coerce straight to a numeric we will end up with [1,2,3] as the values. However, if we coerce to character first, then the values are the correct numeric values.

levels(x)
as.numeric(x)
as.numeric(as.character(x))

However, in your case the vector contains character values and cannot be coerced into a number. And, yes in looking at the error you do, in fact, have character values in this vector. You could use some of the string manipulation functions available in R but, I would suspect that since the data is an alpha-numeric identifier that, just the numeric portion is not unique.

If we introduce an alpha-numeric character into the vector, when we coerce into numeric R will return an NA coercion error and just drop the value. This is where it gets a bit dangerous using the stringsAsFactors=FALSE argument in readOGR. When you coerce you can end up with NA values that are not really NA values but rather a result of a field having some sort of non-numeric value.

(x <- as.factor(c("1","2","3","5","6L")))
as.numeric(as.character(x))

It is not entirely clear in your question but if you are wanting to sum a numeric vector based on each value in a aggregate (summary) vector. This can easily be done using tapply. In this way you can avoid sub-setting data just to get aggregate statistics.

( x <- c(rep(1,10),rep(20,10)) ) 
( y <- runif(20) )
tapply(y, x, sum)

If you are just after the total area of the polygons, you could sidestep this entirely and just use gArea in the rgeos package. The byid=TRUE argument will result in area(s) for each polygon.

***Update, it just occurred to me that a GIS software could be storing large numbers using scientific notation. I would imagine that this would be parsed as a character thus, resulting in a factor in R. If this is the case, these values would be erroneous when coerced. It sounds like it would be best to just get areas in R and not rely on an existing field in the data. If this is the case, and one needs a field in the data, you may have to deal with this in the software that created the data.

1

I faced a similar error just couple of days ago after I upgraded various R stuff.

If you're confident you can assume the field has no characters you can add stringsAsFactors=FALSE to your readOGR statement. Eg.

df<- readOGR("C:/file.shp",layer = "file", verbose = FALSE, stringsAsFactors=FALSE)

Then run as.numeric() on the area field. It would be worth understanding why the field has not been read correctly (possibly it's a 64 bit integer in the file).

4
  • Without understanding what is going on under the hood here, this is dangerious advice and very well could prodece erroneous results on numeric fields that may contain character values. Sep 14, 2017 at 13:26
  • fair enough. I've updated it Sep 14, 2017 at 14:29
  • No, it would not be due to a 64-int value. The only reason would be a character value somewhere in the field. If you look closely at your results I would bet that those values ended up as NA. I guess it is possible that a GIS software is introducing an odd nodata value or field definition that GDAL does not recognize but, that is unlikely. Sep 14, 2017 at 15:25
  • Oh, it could also be attributed to a GIS software using scientific notation for large numbers. This could very well be parsed as a character. Sep 14, 2017 at 15:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.