0

I start with data that looks like this:

Date       Time1            Time2
01/02/2018 01/02/2018 11:12 01/02/2018 13:14
01/03/2018 01/03/2018 09:09 01/03/2018 15:05

and I want output that looks like this:

Date       Time1            Time2            Hour1    Hour2
01/02/2018 01/02/2018 11:12 01/02/2018 13:14 11       13
01/03/2018 01/03/2018 09:09 01/03/2018 15:05  9       15

Assume the times have been successfully coerced into class POSIXct.

In regular R script I use this code to produce my output:

library(lubridate)
a <- ymd_hms(myDF$Time1)
var4 = hour(a)
myDF = cbind(myDF, var4, stringsAsFactors=FALSE)
names(myDF)[4]<-"Hour1"

library(lubridate)
a <- ymd_hms(myDF$Time2)
var5 = hour(a)
myDF = cbind(myDF, var5, stringsAsFactors=FALSE)
names(myDF)[5]<-"Hour2"

But what works in regular R script seems to fail when I try to run the exact same code in a shiny app.

When I try to run this code:

shinyServer(function(input, output))({
 output$contents <- renderTable({
  inFile <- input$file1
  if (is.null(inFile))
   return(NULL)
  myDF = read.csv(inFile$datapath, sep=",")

  timesData = myDF[,c(2:3)]
  timesData$Time1 = as.POSIXct(timesData$Time1, format="%m/%d/%Y %H:%M", 
   tz="GMT")
  timesData$Time2 = as.POSIXct(timesData$Time2, format="%m/%d/%Y %H:%M", 
   tz="GMT")

  library(lubridate)
  a <- ymd_hms(timesData$Time1)
  var4 = hour(a)
  myDF = cbind(myDF, var4, stringsAsFactors=FALSE)
  names(myDF)[4]<-"Hour1"

  library(lubridate)
  a <- ymd_hms(timesData$Time2)
  var5 = hour(a)
  myDF = cbind(myDF, var5, stringsAsFactors=FALSE)
  names(myDF)[5]<-"Hour2"
 })
})

shinyui(
 mainPanel(
  tableOutupt("contents")
 )
))

I get this as my output:

Date       Time1            Time2            Hour1    Hour2
01/02/2018 01/02/2018 11:12 01/02/2018 13:14 18       18
01/03/2018 01/03/2018 09:09 01/03/2018 15:05 18       18

It fills in every row of both hour columns with "18" and when I tried using "a <- ymd_hm(timesData$Time2)" it filled every row of both hour columns with "NA" instead. What do I have to do to make it fill in the rows of my hour columns with the actual hours?

Jennifer B.
  • 163
  • 1
  • 4
  • 10

1 Answers1

0

I can't reproduce your Shiny code as you're missing the ui as well as some objects such as namedDF.

But even your regular script doesn't yield the result you're expecting.

I made the data reproducible with the dput function. (See reproducible examples)

library(tidyverse)
myDF <- structure(list(Date = c("01/02/2018", "01/03/2018"), Time1 = c("01/02/2018 11:12", 
                                                                       "01/03/2018 09:09"), Time2 = c("01/02/2018 13:14", "01/03/2018 15:05"
                                                                       )), .Names = c("Date", "Time1", "Time2"), class = c("tbl_df", 
                                                                                                                           "tbl", "data.frame"), row.names = 1:2)

This is the same data that you pasted.

myDF
# # A tibble: 2 x 3
# Date       Time1            Time2           
# <chr>      <chr>            <chr>           
# 1 01/02/2018 01/02/2018 11:12 01/02/2018 13:14
# 2 01/03/2018 01/03/2018 09:09 01/03/2018 15:05

Now, if you use ymd_hms, you can see that it fails to parse the datetime correctly. (The hours are parsed as 18, which corresponds with your example)

ymd_hms(myDF$Time1)
# [1] "2001-02-20 18:11:12 UTC" "2001-03-20 18:09:09 UTC"

What you can do instead is parse with the parse_datetime function, specifying the format (See ?parse_datetime for details).

And then use the hour function to subset the hours from the datetime.

myDF <- myDF %>% mutate(
  Time1 = parse_datetime(Time1, format = "%m/%d/%Y %H:%M"),
  Time2 = parse_datetime(Time2, format = "%m/%d/%Y %H:%M"),
  Hour1 = hour(Time1),
  Hour2 = hour(Time2)
)

Result:

myDF
# A tibble: 2 x 5
Date       Time1               Time2               Hour1 Hour2
<chr>      <dttm>              <dttm>              <int> <int>
1 01/02/2018 2018-01-02 11:12:00 2018-01-02 13:14:00    11    13
2 01/03/2018 2018-01-03 09:09:00 2018-01-03 15:05:00     9    15
GyD
  • 3,902
  • 2
  • 18
  • 28
  • I attempted GyD's solution and got an error message: Evaluation error: could not find function "parse_datetime". I tried to use parse_date_time() instead, like this: Time1 = parse_date_time(timesData$Tender, orders = "%m/%d/%Y %H:%M") and then Hour1 = hour(Time1) but all I get is "Warning: All formats failed to parse. No formats found." – Jennifer B. Jan 15 '18 at 23:49
  • @JenniferB Did you install and load the `tidyverse`? The `parse_datetime` function is in the `readr` package, which is part of the `tidyverse` – GyD Jan 16 '18 at 09:25
  • Thank you Gyd. I did not have the tidyverse packages installed. After I installed them and tried your solution again it worked! – Jennifer B. Jan 16 '18 at 22:37