Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SPC square-bracket horizon subsetting with index of length 1 causes Spatial errors #85

Closed
brownag opened this issue Feb 15, 2019 · 6 comments
Labels

Comments

@brownag
Copy link
Member

brownag commented Feb 15, 2019

I first noticed this (SPDF results) when I was trying to use horizon-index subsetting on multi-profile SPCs for early versions of the Loafercreek demo. I never really investigated it further, but it seemed like a bug. I've also noticed that accessing the @sp slot results in an error before elevation of the SPC to have SpatialPoints.

However, when I was investigating some of the logic in clod.hz.ids() for new glom() demo, I ran into this problem again. Check out this example.

library(soilDB)
data("loafercreek")

one <- loafercreek[13]

plot(one)

# there is a horizon with depths 18 to 30 cm, but top and bottom within it
my.id <- clod.hz.ids(one, 19, 29)

# clod.hz.ids correctly returns horizon index #3...
the.hz.id <- which(hzID(one) %in% my.id)

# we match just a single horizon
the.hz.id

# error! related to the Spatial slot not being filled out
# but first it returns a SpatialPointsDataFrame???
one[,the.hz.id]

# index of length 2 results in a SPC... 
# the spatial data are more filled out... min/max = 0 and NA
one[,the.hz.id:(the.hz.id+1)]

# error... subscript out of bounds?
slot(one, 'sp')

# data.frame subsetting using the row index works as expected
horizons(one)[the.hz.id,]$hzID == my.id

# try promoting to spatial...
coordinates(loafercreek) <- ~ x_std + y_std
proj4string(loafercreek) <- "+proj=longlat +datum=WGS84"
one.sp <- loafercreek[13]

# if we try to index using it... no error, but we get a SPDF... 
# with site _and_ horizon attributes all smasherated in there
res <- one.sp[,the.hz.id]

class(res)

# yikes.
names(res)

Key error message:

one[,the.hz.id]
result is a SpatialPointsDataFrame object
Error in validObject(.Object) :
invalid class “SpatialPoints” object: spatial.dimension should be 2 or more

@brownag brownag added the bug label Feb 15, 2019
@brownag
Copy link
Member Author

brownag commented Feb 15, 2019

glom() allows the result to be returned as either an SPC (default) or a data.frame via the as.data.frame argument. If your result returns just a single horizon, the glom() will fail due to the above mentioned Spatial error and the default setting is used.

Note: there is an unrelated issue for fixing some edge cases in clod.hz.ids() -- it may be related to issues with single horizon results, but is not the cause of the Spatial error #86

@dylanbeaudette
Copy link
Member

dylanbeaudette commented Mar 15, 2019

I am pretty sure that this is now fixed for all new SoilProfileCollection objects. Added new tests and the following example seems to work. Note that there is a new function for testing non-placeholder SpatialPoints.

This issue is mostly resolved for SoilProfileCollection object created before today because @sp contains an invalid object. rebuildSPC() can fix older objects. I'll do this for all sample data in aqp and soilDB.

Simple example.

library(aqp)

d <- data.frame(
  id='001',
  name=c('A', 'A/E', 'A/E', 'Bhs1', 'Bhs2', 'C1', 'C2'),
  top=c(0,5,5,10,20,50,80),
  bottom=c(5,10,10,20,50,80,100),
  var=c(15, 4, 8, 15, 18, 2, 3),
  v2=1,
  stringsAsFactors=FALSE
  )

depths(d) <- id ~ top + bottom

# check: https://github.com/ncss-tech/aqp/issues/85
d@sp

# new check for valid SpatialPoints
validSpatialData(d)

# error
slice(d, 0:50 ~ ., strict=TRUE)

# warnings
s <- slice(d, 0:50 ~ ., strict=FALSE)

# works now
# previously an error due to 
# faulty logic testing for 'real' SpatialPoints data
s[1, 8]

@dylanbeaudette
Copy link
Member

@brownag I'll close after you test.

dylanbeaudette added a commit that referenced this issue Mar 15, 2019
@brownag
Copy link
Member Author

brownag commented Mar 18, 2019

Still errors with an uninitialized spatial object. This is with the latest version of soilDB and aqp (reinstalled several times, both last friday and toda)

# error... subscript out of bounds?
slot(one, 'sp')

slot(one, 'sp')
class : SpatialPoints
features : 1
Error in e[1, 2] : subscript out of bounds

# data.frame subsetting using the row index works as expected
horizons(one)[the.hz.id,]$hzID == my.id

# try promoting to spatial...
coordinates(loafercreek) <- ~ x_std + y_std
proj4string(loafercreek) <- "+proj=longlat +datum=WGS84"
one.sp <- loafercreek[13]

works when initialized

slot(one.sp, 'sp')

slot(one.sp, 'sp')
class : SpatialPoints
features : 1
extent : -120.3303, -120.3303, 37.75555, 37.75555 (xmin, xmax, ymin, ymax)
coord. ref. : +proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0

@brownag
Copy link
Member Author

brownag commented Mar 18, 2019

This is still an issue

# if we try to index using it... no error, but we get a SPDF... 
# with site _and_ horizon attributes all smasherated in there
res <- one.sp[,the.hz.id]

@dylanbeaudette
Copy link
Member

The underlying problem has been fixed, but some kind of namespace-related bug is preventing the new S4 class from being used. This only happens when loading the soilDB package.

Moving this into a new soilDB issue.

The following works fine:

library(aqp)
data("loafercreek", package = 'soilDB')

d <- data.frame(
  id='001',
  name=c('A', 'A/E', 'A/E', 'Bhs1', 'Bhs2', 'C1', 'C2'),
  top=c(0,5,5,10,20,50,80),
  bottom=c(5,10,10,20,50,80,100),
  var=c(15, 4, 8, 15, 18, 2, 3),
  v2=1,
  stringsAsFactors=FALSE
)

depths(d) <- id ~ top + bottom

slot(d, 'sp')
slot(loafercreek, 'sp')

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants