【问题标题】:How to detect TIME when reading from an excel sheet using R使用R从excel表中读取时如何检测时间
【发布时间】:2019-02-01 06:56:11
【问题描述】:

问题是,当我使用 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

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

【问题讨论】:

    标签: r openxlsx


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      我的第一个猜测是 read.xlsx() 在读取文件时试图猜测 .xlsx 中的日期列,并且奇怪地将时间从 %I:%M %p 格式转换为 24 小时的分数(因为例如 0.3333333 * 24 = 7.999999 which is exactly 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
      

      【讨论】:

        【解决方案3】:

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

        • 使用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
        

        【讨论】:

          猜你喜欢
          • 2019-06-13
          • 2016-03-04
          • 2013-07-05
          • 2017-02-20
          • 1970-01-01
          • 2011-11-21
          • 1970-01-01
          • 2020-01-09
          相关资源
          最近更新 更多