如何在使用R读取excel表时检测TIME

  • 本文关键字:TIME excel 读取 r openxlsx
  • 更新时间 :
  • 英文 :


问题是,当我使用openxlsx包中的read.xlsx从excel表读取R时,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

我不知道它为什么会这样做,也不知道是否有办法解决这个问题,因为我需要使用日期和时间来进行一些计算。

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)))

我的第一个猜测是,read.xlsx()在读取文件时试图猜测.xlsx中看起来像日期的列,并奇怪地将时间从%I:%M %p格式转换为24小时的小数(因为例如0.3333333 * 24 = 7.999999,它正好是8.0)。但后来我注意到,如果我将参数detectDates更改为FALSE,则没有什么真正的变化-它输出相同的数据帧。所以它什么也没猜,它只是照原样读取TIME

如果您尝试在Excel工作簿中编辑10:00 PM,您会发现它实际上存储为22:00:00。那么,为什么最后它被表示为24的一个分数呢?!我不知道,我希望有人能解释一下。

@与openxlsx::read.xlsx()相比,Randall方法确实是一个很好的选择。注意,read_xlsx()TIME识别为%H:%M:%S,并将其转换为伪POSIXct/POSIXt对象,即1899-12-31 08:00:001899-12-31 22:00:00

令人惊讶的是,read_xlsx()没有识别出DATE具有%d-%m-%Y格式,并将其解释为character。这意味着我们需要将两个变量转换为适当的格式,以便获得所需的输出。

我认为我们不需要使用gsub来从POSIXct对象获得12小时的时钟时间,为此使用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

我遇到了同样的问题,并按如下方式解决了它——快速而肮脏:

  • 使用readxl:read_excel()读取数据。

  • 在不失一般性的情况下,我们只考虑从"0.72222222222222"获得17:20,而不是包含时间数据的列。请注意,从excel文件中读取值可能有不需要的类型,但对于计算,我们需要数字。

x <- as.numeric("0.72222222222222")*24 
minutes <- round((x %% 1)*60, digits = 0) 
hours <- round(x - minutes/60, digits = 0)
if (minutes < 10){ #if minutes is a single digit need to insert a preceding 0
minutes= paste0("0",minutes)
}
paste0(hours, ":", minutes)
#17:20

在chron包中使用times()函数将给出解决方案:

library(chron)
times(0.111)

[1] 02:39:50

  1. 将时间值读取为"日期":

    test <- read_excel('dfin.xlsx', col_types = c("date"), ...)
    
  2. 然后用substr()修剪得到时间:

    test <- substr(test,12,16)
    

相关内容

最新更新