Henrik-P · GitHub

Using dplyr data manipulation functions on a grouped data frame which contains a variable of class difftime generates the error:

Error in eval(expr, envir, enclos) :
  column 'the-name-of-the-difftime column' has unsupported type

I illustrate this using some toy data with a grouping variable (grp), a column with some values (val), two date columns (date1, date2), and a variable of class difftime (the difference between date1 and date2):

df <- data.frame(
  grp =   c(1, 1,  2, 2),
  val =   c(1, 3,  4, 6),
  date1 = c(rep(Sys.Date() - 10, 2), rep(Sys.Date() - 20, 2)),
  date2 = Sys.Date() + 1:2)
df$diffdate <- difftime(df$date2, df$date1, unit = "days")
df

I tried to add the mean of vals within each group to the original data set. The desired output can be created using ddply :

library(plyr)
df_dd <- ddply(.data = df, .variables = .(grp), mutate,
               mean_val = mean(val))
df_dd
#   grp val      date1      date2 diffdate mean_val
#1   1   1 2014-04-04 2014-04-15  11 days        2
#2   1   3 2014-04-04 2014-04-16  12 days        2
#3   2   4 2014-03-25 2014-04-15  21 days        5
#4   2   6 2014-03-25 2014-04-16  22 days        5
str(df_dd)
# ...
# $ diffdate:Class 'difftime'

When I try to create the same output with dplyr, an error is generated

detach("package:plyr", unload = TRUE)
library(dplyr)
df %.%
  group_by(grp) %.%
  mutate(
    mean_val = mean(val)
  )
# Error in eval(expr, envir, enclos) :
#   column 'diffdate' has unsupported type

Just to check, the same error is generated when the difftime variable is itself subject to the calculation, e.g.

df %.%
  group_by(grp) %.%
  mutate(
    mean_diff = mean(diffdate)
    )

...or when using (toy examples of) summarise, filter, select or arrange:

df %.%
  group_by(grp) %.%
  summarise(
    mean_val = mean(val)
  )
df %.%
  group_by(grp) %.%
  filter(
    sum(val) > 5
  )
df %.%
  group_by(grp) %.%
  select(-val)
df %.%
  group_by(grp) %.%
  arrange(-val)

The difftime variable does not cause any problem when mutate is used on an ungrouped data frame:

df2 <- mutate(df, diffdate = difftime(date2, date1, unit = "days"))
df2
str(df2)
mutate(df2, mean_val = mean(val), mean_diff = mean(diffdate))

...or on an ungrouped 'tbl_df':

tbl <- tbl_df(df)
mutate(tbl, mean_val = mean(val), mean_diff = mean(diffdate))

Neither does the difftime variable cause any problem when various dplyr data manipulation functions are applied on a grouped data.table version of df:

library(data.table)
dt <- data.table(df)
dt2 <- dt %.%
  group_by(grp) %.%
  mutate(
    mean_val = mean(val)
  )
dt2
# Source: local data table [4 x 6]
# Groups: grp
#   grp val      date1      date2 diffdate mean_val
#1   1   1 2014-04-05 2014-04-16  11 days        2
#2   1   3 2014-04-05 2014-04-17  12 days        2
#3   2   4 2014-03-26 2014-04-16  21 days        5
#4   2   6 2014-03-26 2014-04-17  22 days        5
str(dt2)
dt %.%
  group_by(grp) %.%
  summarise(
    mean_val = mean(val)
  )
dt %.%
  group_by(grp) %.%
  filter(
    sum(val) > 5
  )
dt %.%
  group_by(grp) %.%
  select(-val)
dt %.%
  group_by(grp) %.%
  arrange(-val)

My current quick and dirty workaround is to convert the difftime variable to numeric:

df$diffdate <- as.numeric(difftime(df$date2, df$date1, unit = "days"))
df %.%
  group_by(grp) %.%
  mutate(
    mean_val = mean(val)
  )

However, there are quite a few methods for the difftime class (see Detail in ?difftime). Thus, it would be nice if dplyr could handle grouped data frames containing a variable of class difftime.

Search on SO and google for 'dplyr difftime "Error in eval(expr, envir, enclos)" : column has unsupported type' gave no hits.

Thanks a lot for your great work with a fantastic package.

Best regards,

Henrik

R version 3.1.0 (2014-04-10)
Platform: x86_64-w64-mingw32/x64 (64-bit)
data.table_1.9.2, dplyr_0.1.3, plyr_1.8.1

Read the original on github.com ↗