7

问题是,当我使用read.xlsxfrom openxlsxpackage 从 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

我不确定为什么会这样,以及是否有办法解决这个问题,因为我需要同时使用 DATE 和 TIME 来进行一些计算。

4

3 回答 3

6

R 确实没有时间格式,所以我建议在 using 中阅读它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)))
于 2019-02-01T07:25:15.280 回答
5

我的第一个猜测是,read.xlsx()它试图在读取文件时猜测 .xlsx 中的日期列,并且奇怪地将时间从%I:%M %p格式转换为 24 小时的分数(因为例如0.3333333 * 24 = 7.999999 正好是 8.0)。但后来我注意到,如果我将参数更改为什么detectDatesFALSE没有真正改变 - 它输出相同的数据帧。所以它什么都猜不到,它只是按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:001899-12-31 22:00:00

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

我认为我们不需要使用gsubPOSIXct对象获取 12 小时时钟时间,它很容易format用于此目的。将DATEfrom%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
于 2019-02-01T16:04:18.523 回答
1

我遇到了同样的问题并解决了如下问题 - 快速而肮脏:

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

  • 不失一般性,我们只看17:20从而"0.72222222222222"不是包含时间数据的列中获取。请注意,从 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
于 2021-09-13T14:36:17.033 回答