0

I am trying to compute the log of a column of a zoo data frame in R. Although all the data are positives numerics, R says (non-numeric argument to mathematical function).

Weirdly it works when applying to the data before they are transformed to a zoo data frame.

I cannot understand why.

Here is my code :

library(zoo)
data <- read.csv(file="dataecm/data.csv", sep = ";", stringsAsFactors=FALSE)
log(data$GDP) ### Works
datats<-zoo(data, order.by = data$DATE)
log(datats$GDP) ### Does not work ->  (non-numeric argument to mathematical function)

By the way, when using View(datats) the zoo data frame look exactly the same as the dataframe read from csv.

Here is the dataset : enter image description here

Thank you for your help.

Jean G
  • 153
  • 1
  • 1
  • 7
  • It will help people answer if you follow the guidelines here to provide a reproducible example: https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example For instance, include a small dataset with `dput` that can be used to reproduce the issue. And include your library calls, e.g., `library(zoo)`. – Tim Goodman Apr 20 '20 at 14:38
  • Regarding your question, have you tried checking whether `class(datats$GDP)` is different than `class(data$GDP)`? – Tim Goodman Apr 20 '20 at 14:39
  • You might want to try typing `class(datats$GDP)` into the dataframe after the `zoo` transformation to make sure it didn't alter the class to a factor or some other data type. – Matt Apr 20 '20 at 14:39
  • class(datats$GDP) [1] "zoo" class(data$GDP) [1] "numeric" – Jean G Apr 20 '20 at 14:42
  • 1
    If you share the data using `dput` as per those instructions I linked, then we'll get something we can copy into our own environment to reproduce the issue. – Tim Goodman Apr 20 '20 at 15:00
  • Also check `class(coredata(datats$GDP))`, since (as stated in the zoo documentation) `coredata` can be used to access the underlying data. – Tim Goodman Apr 20 '20 at 15:19
  • Edward's dataset below is an example of what you'd get by running `dput`, and appears to reproduce the issue. E.g., if you use `datats <- zoo(data, order.by = data$Date)` then you find `class(coredata(datats$GDP))` is `"character"` (which won't work for `log`), whereas if you follow his suggestion and do `datats <- zoo(data$GDP, order.by = data$Date)` then `class(coredata(datats))` is `"integer", which `log` will accept. – Tim Goodman Apr 20 '20 at 15:22
  • But note that it would be impossible for us to be *sure* that was your issue from what you posted, because it depends on the data type of the DATE column. If you just change `structure(c(10957, 10958, 10959), class = "Date")` to `c(10957, 10958, 10959)` (or to, say, `c(1982, 1983, 1984)`), it no longer reproduces the issue. So this illustrates why it's important to share your data using `dput`, which will capture the data types as wells as the values. Just something to keep in mind for next time you post a question. :) – Tim Goodman Apr 20 '20 at 15:37

1 Answers1

3

Don't include the whole data as the first argument to zoo.

datats <- zoo(data$GDP, order.by = data$DATE)

datats is now a time-series containing only the GDP at your given dates

Then log on datats should work

log(datats)
#2000-01-01 2000-01-02 2000-01-03 
#  11.52307   11.72364   13.39135

Data:

data <- structure(list(DATE = structure(c(10957, 10958, 10959), class = "Date"), 
    GDP = c(101020L, 123456L, 654321L)), row.names = c(NA, -3L
), class = "data.frame")
Edward
  • 10,360
  • 2
  • 11
  • 26