0

I recently started coding using R for my master thesis and am still learning.

In order to treat some meteorological data I tried creating a function. The original file is a csv file with dates and rainfalls. I extracted the dates and created a POSIXct object with all my dates and then an xts object with my dates and rainfalls.

mesdonnees <- mesdonnees[26000:30000,]

require('xts')

# Extract characters and define as S....
Syear <- substr(mesdonnees$time, 1, 4)
Smonth <- substr(mesdonnees$time, 6,7)
Sday <- substr(mesdonnees$time, 9, 10)
Shour <- substr(mesdonnees$time, 12, 13)
Sminutes <- substr(mesdonnees$time, 15, 16)

#Gather all parts and use "-" as sep
datetext <- paste(Syear, Smonth, Sday, Shour, Sminutes, sep="-")
#define format of each part of the string
formatdate <- as.POSIXct(datetext, format="%Y-%m-%d-%H-%M", tz = "GMT")

xtsdata <- xts(mesdonnees[,2:3], order.by = formatdate, header = TRUE)

I then wrote a function that will sum the value of difftime and store it in a variable x when it's <= than 20 minutes or add 20 to x and store the remaining difftime in a variable y when difftime is > 20 minutes

myfun <- function(CHANGE){       # CHANGE = formatdate or xtsdata
x <- as.difftime(0,format = "%M", units = "mins")
y <- as.difftime(0,format = "%M", units = "mins")
for (i in 2:length(CHANGE)) {
    if (difftime(CHANGE[i],CHANGE[i-1],units = "mins") <= as.difftime(20,format = "%M",units = "mins")) {
    x <- x + difftime(CHANGE[i],CHANGE[i-1],units = "mins")
    } else {
    x <- x + 20
    y <- y + difftime(CHANGE[i],CHANGE[i-1],units = "mins") - 20
    }
   }
return(list(paste("x = ",x , sep = ""),paste("y = ",y , sep = "")))
}

This function works really fine when working with a ´as.POSIXct´ object (formatdate), but won't work when I try to run it with an ´xts´ object (xtsdata). When doing so, I get the following error: do not know how to convert 'x' to class “POSIXlt”. Why should x be changed to POSIXct when it is a time difference?

Next step, which I can't manage to get working either, is using apply.monthly to this function using `apply.monthly(xtsdata,myfun).

Currently, when trying to use apply.monthly(formatdate,myfun)I get the following error: Error in if (difftime(CHANGE[i], CHANGE[i - 1], units = "mins") <= as.difftime(20, : missing value where TRUE/FALSE needed

and when trying apply.monthly(xtsdata,myfun) I get the following error: Error in as.POSIXlt.default(x, tz, ...) : do not know how to convert 'x' to class “POSIXlt”

Any advice on how to get my function working properly and how to apply apply.monthly would greatly help. Thank your for your help !


Edit for further details: (sid: identification of the meteo data, I don't need that column), time = date, value = rainfall

> head(mesdonnees)
      sid                time value
26000 100 2010-07-14 11:50:00     0
26001 100 2010-07-14 12:10:00     0
26002 100 2010-07-14 12:20:00     0
26003 100 2010-07-14 12:30:00     0
26004 100 2010-07-14 12:41:00     0
26005 100 2010-07-14 12:50:00     0

> head(formatdate)
[1] "2010-07-14 11:50:00 GMT" "2010-07-14 12:10:00 GMT"
[3] "2010-07-14 12:20:00 GMT" "2010-07-14 12:30:00 GMT"
[5] "2010-07-14 12:41:00 GMT" "2010-07-14 12:50:00 GMT"

> head(xtsdata)
                    time                  value
2010-07-14 11:50:00 "2010-07-14 11:50:00" " 0.00"
2010-07-14 12:10:00 "2010-07-14 12:10:00" " 0.00"
2010-07-14 12:20:00 "2010-07-14 12:20:00" " 0.00"
2010-07-14 12:30:00 "2010-07-14 12:30:00" " 0.00"

I have to estimate the rainfalls per month from those data (mesdonnees). The initial data give the "Instant precipitations" at a precise time and I should have a value every 10 minutes. However, it is not the case and sometimes I don't have a value until days later (and no NA line to notice the missing values). I hope this explanation is better?

Axel
  • 47
  • 7
  • Could you do `head(mesdonnees)` so that we get an idea of how the data looks? And what is the underlying problem you are trying to solve? When you write "treat some meteorological data", what kind of treatment are you thinking of? – AkselA May 17 '17 at 18:16

1 Answers1

0

You could probably read your CSV directly into an xts or zoo object. But you don't specify the format of the data in the CSV, so my answer will assume mesdonnees is a data.frame.

Since you don't need the sid column, all you need to do to create an xts object is:

xtsdata <- xts(mesdonnees$value, as.POSIXct(mesdonnees$time))

In the case that mesdonnees$time is a factor, you'll need to convert it to character first.

xtsdata <- xts(mesdonnees$value, as.POSIXct(as.character(mesdonnees$time)))

Then you can call apply.monthly(xtsdata, ...) with whatever function you want to use to create summary statistics by month. For example:

apply.monthly(xtsdata, quantile)
Joshua Ulrich
  • 173,410
  • 32
  • 338
  • 418
  • Hello, thank you for your advice! While it saves quite some writing in the `xts` creation, I still can't use the `difftime` function to the `xts` object (R says it can't convert `'x'`to as.POSIXlt`, although it recognises the date format – Axel May 18 '17 at 10:48
  • @legardien: it's unclear why you need to use `difftime`. – Joshua Ulrich May 18 '17 at 11:46
  • I needed `difftime` to make sure that de difference between two lines did not exceed 20 minutes (I used it in the function). In the end I received additional info on the data as well as some corrections about units, which mean I could do a basic `apply.monthly(xtsdata,mean)` and work with this. Thank you for the `xts`creation tips, it makes my code so much shorter and cleaner. – Axel May 18 '17 at 13:29