Как определить ВРЕМЯ при чтении с листа Excel с помощью R

Проблема в том, что когда я читаю с листа Excel в R, используя read.xlsx из пакета openxlsx, столбец TIME преобразуется в дробь.

Вот пример,

dfin <-
DATE          TIME
15/02/2015    8:00 AM
22/01/2014    10:00 PM

library(openxlsx)
test <-  read.xlsx("dfin.xlsx", sheet = 1,
                 detectDates=TRUE, skipEmptyRows = TRUE,
                 skipEmptyCols = TRUE, rows = NULL, cols = NULL, check.names = FALSE,
                 namedRegion = NULL, na.strings = "NA", fillMergedCells = FALSE) 

Выход:

  DATE        TIME
  2015-02-15  0.3333333
  2014-01-22  0.9166667

Я не уверен, почему это происходит и есть ли способ исправить это, поскольку мне нужно использовать как DATE, так и TIME для выполнения некоторых вычислений.


person Amer    schedule 01.02.2019    source источник


Ответы (2)


На самом деле R не имеет формата времени, поэтому я предлагаю читать его, используя read_excel, который автоматически определяет тип столбца. Это превратит его в формат даты и времени со случайной датой, которую вы затем можете удалить, прежде чем преобразовать ее в правильную отметку времени.

library(readxl)
library(lubridate)

test <- read_excel('dfin.xlsx',trim_ws = TRUE) %>%
  #return the TIME column to the way it is written in Excel
  mutate(TIME = as.character(gsub(".* ","",TIME)),
  #format the date column
     DATE = dmy(DATE),
  #turn it into a timestamp
     TIMESTAMP = as.POSIXct(paste(DATE,TIME)))
person Randall Helms    schedule 01.02.2019

Мое первое предположение заключалось в том, что read.xlsx() пытается угадать столбцы даты в .xlsx, когда читает файл, и странным образом преобразует время из формата %I:%M %p в доли 24 часов (потому что, например, 0.3333333 * 24 = 7.999999 что равно 8.0). Но позже я заметил, что если я изменю параметр detectDates на FALSE, ничего не изменится - он выводит тот же кадр данных. Так что он ничего не угадывает, он просто читает TIME как есть.

Если вы попытаетесь отредактировать 10:00 PM в книге Excel, вы увидите, что на самом деле он хранится как 22:00:00. Так почему же в конце оно представлено в виде дроби от 24?! Я не знаю, и я надеюсь, что кто-то может объяснить это.

Подход @Randall - действительно хорошая альтернатива по сравнению с openxlsx::read.xlsx(). Обратите внимание, что read_xlsx() распознает TIME как %H:%M:%S и преобразует его в фиктивный объект POSIXct/POSIXt, то есть 1899-12-31 08:00:00 и 1899-12-31 22:00:00.

Удивительно, но read_xlsx() не распознает, что DATE имеет формат %d-%m-%Y, и интерпретирует его как character. Это означает, что нам нужно преобразовать обе переменные в соответствующий формат, чтобы получить желаемый результат.

Я не думаю, что нам нужно использовать gsub для получения 12-часового времени из объекта POSIXct, гораздо проще использовать format для этой цели. А преобразовать DATE из %d-%m-%Y в %Y-%m-%d формат еще проще:

library(dplyr)
library(readxl)

read_xlsx("myfile.xlsx") %>%
  mutate(
    DATE = as.Date(DATE, "%d/%m/%Y"), 
    TIME = format(TIME, "%I:%M %p")   # “That’s what I do: I drink and I know things.”
    )

Что производит:

# A tibble: 2 x 2
  DATE       TIME    
  <date>     <chr>   
1 2015-02-15 08:00 AM
2 2014-01-22 10:00 PM
person utubun    schedule 01.02.2019