6

If you have a data.frame with numeric columns the conversion is without problems, as explained here.

dtf=data.frame(matrix(rep(5,10),ncol=2))
#str(dtf)
dtfz <- zoo(dtf)
class(dtfz)
#[1] "zoo"
str(as.data.frame(dtfz))
#'data.frame':  5 obs. of  2 variables:
# $ X1: num  5 5 5 5 5
# $ X2: num  5 5 5 5 5

But if you have a data.frame with text columns everything is converted to factors, even when setting stringsAsFactors = FALSE

dtf=data.frame(matrix(rep("d",10),ncol=2),stringsAsFactors = FALSE)
#str(dtf)
dtfz <- zoo(dtf)
#class(dtfz)
#dtfz

All the following convert the strings to factors:

str(as.data.frame(dtfz))
str(as.data.frame(dtfz,stringsAsFactors = FALSE))
str(data.frame(dtfz))
str(data.frame(dtfz,stringsAsFactors = FALSE))
str(as.data.frame(dtfz, check.names=FALSE, row.names=NULL,stringsAsFactors = FALSE))

#'data.frame':  5 obs. of  2 variables:
# $ X1: Factor w/ 1 level "d": 1 1 1 1 1
# $ X2: Factor w/ 1 level "d": 1 1 1 1 1

How to avoid this behaviour when the data.frame has many text columns?

Robert
  • 5,038
  • 1
  • 25
  • 43
  • 1
    `zoo:::as.data.frame.zoo` doesn't seem to respect other arguments to `as.data.frame` - the first line is `y <- as.data.frame(coredata(x), optional = optional)` with no `...`. `str(as.data.frame(as.matrix(dtfz), stringsAsFactors=FALSE))` might work as a work-around. – thelatemail Sep 11 '17 at 22:54
  • 1
    Good point @ thelatemail! Then this works: `str(base:::as.data.frame(coredata(dtfz),stringsAsFactors = FALSE))` – Robert Sep 11 '17 at 23:00
  • 1
    Answer your own question - reap the sweet reputation points ;-) – thelatemail Sep 11 '17 at 23:02
  • Achim has now fixed this in zoo 1.8.1 (the development version) so that `stringsAsFactors=` will not be ignored in `as.data.frame.zoo`. – G. Grothendieck Sep 12 '17 at 04:08

1 Answers1

3

I found the solution based on a comment by @thelatemail. It works for the actual version of zoo (Sept/2017). As @G. Grothendieck commented, the future versions of zoo will consider the stringsAsFactors = FALSE argument.

str(base:::as.data.frame(coredata(dtfz),stringsAsFactors = FALSE))
#'data.frame':  5 obs. of  2 variables:
# $ X1: chr  "d" "d" "d" "d" ...
# $ X2: chr  "d" "d" "d" "d" ...
Robert
  • 5,038
  • 1
  • 25
  • 43