0

the unit of tick_count column is 100 millisecond. I want to plus the tick_count time on date_time. But the result doesn't execute addition correctly. For example, the second value should be "2014-08-15 12:51:02.6 EEST" rather than "2014-08-15 12:51:02.5 EEST", I don't know why this happened. It caused a serious impact on my result because some time it lead to two or three rows having a same time. How to deal with this situation?

>head(status306$date_time)
#[1] "2014-08-15 12:51:01 EEST" "2014-08-15 12:51:01 EEST" "2014-08-15 12:51:01 EEST"
#[4] "2014-08-15 12:51:01 EEST" "2014-08-15 12:51:01 EEST" "2014-08-15 12:51:01 EEST"
> head(status306$tick_count/10)
#[1] 0.0 1.6 1.7 1.1 2.6 2.8
> head(status306$date_time +status306$tick_count/10)
#[1] "2014-08-15 12:51:01.0 EEST" "2014-08-15 12:51:02.5 EEST" "2014-08-15 12:51:02.7 EEST"
#[4] "2014-08-15 12:51:02.0 EEST" "2014-08-15 12:51:03.5 EEST" "2014-08-15 12:51:03.7 EEST"

Update

Here is the original data frame, I just knew it :p

structure(list(grint = c("C51CCF4CAACGGCC44", "C55CCF4CCCCGGCC44", 
"C55CCF4CCCCGGCC44", "C55CCF4CCCCGGCC44", "C55CCF4CCC011CC44", 
"C55CCF4CCC011CC44"), dint = c("0000010100001010000000000001110000000001100001000000", 
"0000010100001010000000000001110000000001100001000000", "0100010100001010000000000001110000000001100001000000", 
"0100010100001011000000000001110000000001100001000000", "0000010100001011000000000001110000000001100001000000", 
"0000010100001011000000000000100000000001100001000000"), tick_count = c(0L, 
16L, 17L, 11L, 26L, 28L), date_time = structure(c(1408096261, 
1408096261, 1408096261, 1408096261, 1408096261, 1408096261), class = c("POSIXct", 
"POSIXt"), tzone = ""), detector_signal_levels = c("135,1,163,1,165,5,167,167,5,167,5,163,3,169,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,", 
"135,5,163,1,165,5,167,167,5,167,5,163,3,169,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,", 
"135,5,163,1,165,5,167,167,5,167,5,163,3,169,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,", 
"135,5,163,1,165,5,167,7,5,167,5,163,3,169,77,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,", 
"135,5,163,1,165,5,167,7,9,167,1,163,3,169,121,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,", 
"135,5,163,1,165,5,167,7,9,15,1,163,3,169,123,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"
)), .Names = c("grint", "dint", "tick_count", "date_time", "detector_signal_levels"
), row.names = c(NA, 6L), class = "data.frame")
chenchenmomo
  • 233
  • 1
  • 3
  • 16
  • I suspect the reason is that your `$date_time` values include milliseconds, so you're not adding what you think you're adding. What's displayed is not necessarily of the same precision as the actual values. Are the `$date_time` POSIX-class? – Carl Witthoft Aug 29 '14 at 11:41
  • Yes, I think it is POSIX class. It's quite strange but I don't think the reason is that $date_time values include milliseconds, because actually for the sequence data, they are sent in a packet, date_time is the time of recieving the packet, the time difference is just about $tick_count. – chenchenmomo Aug 29 '14 at 12:17
  • @Chenlu I updated using your `dput` dataset – akrun Aug 29 '14 at 12:35

1 Answers1

2

Try: (if your input is character class)

date_time <- c("2014-08-15 12:51:01", "2014-08-15 12:51:01", "2014-08-15 12:51:01",
         "2014-08-15 12:51:01", "2014-08-15 12:51:01", "2014-08-15 12:51:01")

date_time1 <- strptime(date_time, format="%Y-%m-%d %H:%M:%S", tz="EEST")
v1 <- c(0.0, 1.6,1.7,1.1, 2.6, 2.8)

date_time1$sec <- date_time1$sec+v1
op <- options(digits.secs=3)
date_time1
#[1] "2014-08-15 12:51:01.0 EEST" "2014-08-15 12:51:02.6 EEST"
#[3] "2014-08-15 12:51:02.7 EEST" "2014-08-15 12:51:02.1 EEST"
#[5] "2014-08-15 12:51:03.6 EEST" "2014-08-15 12:51:03.8 EEST"

I think I can reproduce your results:

date_time1 <- as.POSIXct(date_time, format="%Y-%m-%d %H:%M:%S", tz="EEST")
date_time1+v1
#[1] "2014-08-15 12:51:01.0 EEST" "2014-08-15 12:51:02.5 EEST"
#[3] "2014-08-15 12:51:02.7 EEST" "2014-08-15 12:51:02.0 EEST"
#[5] "2014-08-15 12:51:03.5 EEST" "2014-08-15 12:51:03.7 EEST"

Update

Convert to POSIXlt and you can get the result you expected (though, I am not sure whether your expected result is correct)

 status306$date_time<- as.POSIXlt(status306$date_time)
 status306$date_time$sec <- with(status306, date_time$sec + tick_count/10)
 status306$date_time
 #[1] "2014-08-15 05:51:01.0 EDT" "2014-08-15 05:51:02.6 EDT"
 #[3] "2014-08-15 05:51:02.7 EDT" "2014-08-15 05:51:02.1 EDT"
 #[5] "2014-08-15 05:51:03.6 EDT" "2014-08-15 05:51:03.8 EDT"

Update2

  status306$date_time[4] <- as.POSIXct("2014-08-15 12:53:59")
  status306$date_time<- as.POSIXlt(status306$date_time)
  val <- with(status306, date_time$sec + tick_count/10)
  status306$date_time$sec <- ifelse(val >=60, val-60, val)
  status306$date_time$min <- ifelse(val >=60, status306$date_time$min+1, status306$date_time$min)

  status306$date_time
  #[1] "2014-08-15 05:51:01.0 EDT" "2014-08-15 05:51:02.6 EDT"
  #[3] "2014-08-15 05:51:02.7 EDT" "2014-08-15 12:54:00.1 EDT"
  #[5] "2014-08-15 05:51:03.6 EDT" "2014-08-15 05:51:03.8 EDT"



 options(op)
akrun
  • 874,273
  • 37
  • 540
  • 662
  • This doesn't address the problem, as you've created character strings as the input. – Carl Witthoft Aug 29 '14 at 11:41
  • @Carl Witthoft The user didn't use `dput`. So, that was the only option for me and I can't comment due to reputation. Also, the character strings are converted by `strptime`. It is not clear from OP's post whether it is `POSIXct` or `POSIXlt` – akrun Aug 29 '14 at 11:42
  • That's fine, but you should put some text in your answer like "If your inputs are chars, then..." – Carl Witthoft Aug 29 '14 at 11:45
  • @Carl Witthoft, sorry that I didn't say that, the input date_time is not character string, it's POSIXct and the type is double. BTW, what's 'dput', I want to know more of that if convenient – chenchenmomo Aug 29 '14 at 12:08
  • 1
    @Chenlu You could use `dput(head(status306))` and copy and paste the output to your post so that others can reproduce the structure that your original dataset has. – akrun Aug 29 '14 at 12:10
  • I updated the question by using the function! Thx for informing the useful function – chenchenmomo Aug 29 '14 at 12:21
  • @akrun, First thanks for your help, but I used the solution, there was still a problem, when `(date_time$sec + tick_count/10) >60`, error happened. The value of second part is overflowing, so things like `2014-08-15 12:53:62.8` occur which should be `2014-08-15 12:53:02.8` correctly. – chenchenmomo Aug 31 '14 at 17:27
  • @Chenlu I think that is one of the reason I mentioned your expected result is not correct. Here, I tried to match your expected result by adding to the `sec` that is extracted instead of adding to the whole part. I guess an `ifelse` would solve this. – akrun Aug 31 '14 at 17:30
  • @akrun, I used `for` loop and `ifelse` but the second part only left integer without millisecond, could you help me demonstrate how to use? Thank you again. – chenchenmomo Sep 02 '14 at 14:50
  • @Chenlu You may also have to do similarly for the `hours` if there are `edge` situations. – akrun Sep 02 '14 at 17:09