Skip to content

Instantly share code, notes, and snippets.

@barryrowlingson
Created August 16, 2014 22:51
Show Gist options
  • Save barryrowlingson/93861ba26005a87d1e0b to your computer and use it in GitHub Desktop.
Save barryrowlingson/93861ba26005a87d1e0b to your computer and use it in GitHub Desktop.
R classes
###
### superclassing is nice
###
require(dplyr)
require(testthat)
set.seed(310366)
classes = c("thingy","data.frame")
d = data.frame(x=1:10, y=rnorm(10))
class(d)=classes
print(d)
# indexing and subset preserve the class
expect_equal(class(d[1:5,]), classes)
expect_equal(class(subset(d, y>0)), classes)
# dplyr doesn't - its just a plain data frame
expect_equal(class(d %.% filter(y>0)), "data.frame")
# Vectors can be superclassed
x = runif(10)
vclasses=c("wotsit",class(x))
class(x)=vclasses
# But indexing loses the extra class
expect_equal(class(x[1:5]),"numeric")
# and stored in a data frame
d2 = data.frame(x=x, y=runif(10), k = sample(letters[1:3],10,TRUE))
expect_equal(class(d2$x), vclasses)
# but indexing and subsetting destroy it
expect_equal(class(d2[1:5,]$x), "numeric")
expect_equal(class(subset(d2,x>.5)$x), "numeric")
# never mind, we can create a class preserving index method
"[.wotsit" <- function(x,i){
z=NextMethod()
class(z)=c("wotsit","numeric")
z
}
# subset vector preserves classes
expect_equal(class(x[1:5]), vclasses)
# also works for data frame subsets
expect_equal(class(d2[1:5,]$x), vclasses)
expect_equal(class(subset(d2,x>.5)$x), vclasses)
# filter using dplyr returns plain class
expect_equal(class((d2 %.% filter(x>0.4))$x), "numeric")
# grouping fails
expect_error({d2 %.% group_by(k)})
# but we can drop that column, group:
d3 = d2 %.% select(y,k) %.% group_by(k)
# and then put it back
d3$x = d2$x
expect_equal(class(d3$x),vclasses)
# and then work on that by group
d3 %.% summarise(m=mean(x))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment