【问题标题】:Create Uniform Date across Varying Formats跨不同格式创建统一日期
【发布时间】:2019-02-22 21:33:44
【问题描述】:

我有一个包含大约 53,000 行的数据集,其中一列测量了进行观察的日期和时间。在数据收集过程中,不知何故,日期的格式从 mm/dd/year 转换为 dd/mm/year,这种情况发生了好几次。但是,我知道每个错误发生的确切行,所以我想知道是否有一种有效的方法可以将它们全部更改为单一格式(我希望它们以 mm/dd/year 为单位,因为这是大多数观察结果在)。

这是我正在谈论的问题的一个示例,从 dd/mm/year 到 mm/dd/year:

data.test = data.frame(Date = c("16/11/2017 8:45 AM", "16/11/2017 9:00 AM", 
"11/16/2017 9:15 AM", "11/16/2017 9:30 AM"), Observed = c(100, 23, 291, 30))
data.test

Date                Observed
16/11/2017 8:45 AM  100         
16/11/2017 9:00 AM  23          
11/16/2017 9:15 AM  291         
11/16/2017 9:30 AM  30  

在我的数据集中,日期是字符,而其余行是数字。

【问题讨论】:

  • 您提到您知道格式已被切换的行。该信息是否可用作标志,您可以根据该标志知道日期是否已切换?
  • 我不确定你的意思,但是收集数据的人给出了发生这种转变的日期,我在数据集中找到了它们。我可以轻松地在发生此切换的行上添加具有某种虚拟标记的另一列。
  • 有两种方法。您可以使用标志(如果可用)来更改日期格式的一种方法,另一种方法可能是检查日期在 mm-dd-yyyy 中是否有效,然后使用它,否则使用 dd-mm-yyyy 格式。 lubridate 提供了一个智能功能来帮助第二个选项。

标签: r date time-series


【解决方案1】:

在这种情况下,我更喜欢使用lubridate::parse_date_time 函数来处理同一列中日期/时间的异构格式

# Sample data.frame
# I have modified one date from sample used by OP to include both AM and PM 
data.test = data.frame(Date = c("16/11/2017 8:45 AM", "16/11/2017 9:00 PM", 
               "11/16/2017 9:15 AM", "11/16/2017 9:30 AM"), Observed = c(100, 23, 291, 30))

#modified column added in consistent format. 
library(lubridate)
data.test$modifeddatetime <- parse_date_time(data.test$Date, c("dmY HM p", "mdY HM p"))

#Change the modfieddatetime column back in character in desired format
data.test$modifeddatetime <- format(data.test$modifeddatetime, format="%m/%d/%Y %H-%M")


data.test
#                 Date Observed  modifeddatetime
# 1 16/11/2017 8:45 AM      100 11/16/2017 08-45
# 2 16/11/2017 9:00 PM       23 11/16/2017 21-00
# 3 11/16/2017 9:15 AM      291 11/16/2017 09-15
# 4 11/16/2017 9:30 AM       30 11/16/2017 09-30

【讨论】:

  • 太棒了!只是出于好奇,有没有办法重新格式化结果(最后一列)以使其与第一列匹配?我对时间序列真的很陌生,所以我确信我什至不需要这样做来进行分析,但我仍然想知道。
  • 是的。你可以这样做。我刚刚以日期/时间格式留下最后一列。您可以通过将其转换为字符来将其更改为所需的格式。
  • @AidenKenny 修改解决方案以更改 mm/dd/yyyy 格式的修改列的格式。
  • 我认为parse_date_time 不够聪明,无法知道“1/12/2019”是 1 月 12 日还是 12 月 1 日。
  • @42- 这就是为什么它优先考虑格式。假设我先提供了dmY,然后是mdY。这意味着如果它无法使用dmY 找到有效日期,它将尝试mdY。一切都取决于 OP 想要如何使用它。
【解决方案2】:

您说您知道需要进行更改的位置(可能是一系列行号),但您没有在示例中给出这些位置,可能是因为它很明显。但是在 mm 和 dd 都小于 13 的情况下,这并不明显。

data.test$Date <- as.character(data.test$Date) # prevent factor issues
dd_mm <- 1:2 # the rows to be changed
repl <-format( as.POSIXct( data.test$Date[dd_mm], format="%d/%m/%Y %H:%M %p"), format="%m/%d/%Y %H:%M %p" )
data.test$Date[dd_mm] <- repl
data.test
#-------------------------------------------
                 Date Observed
1 11/16/2017 08:45 AM      100
2 11/16/2017 09:00 AM       23
3  11/16/2017 9:15 AM      291
4  11/16/2017 9:30 AM       30

【讨论】:

  • 很抱歉没有理解您的担心,所以当月份和日期都小于13时,月份和日期是不明显的!
【解决方案3】:

这是一个有趣的尝试。假设您的第一次观察是正确的格式,则使用一些代码来根据日期应该在哪个月份检查最合理的日期格式。它如何处理月份的变化我还不完全确定.

只要第一次观察是正确的,它就会以正确的格式继续下去,直到遇到一个模棱两可的日期。在这一点上,它会与之前应该正确的观察月份进行检查。如果它们匹配,则正确预测当前的模棱两可的观察,如果不匹配,则选择其他格式。再次,当月份切换并且模棱两可的热门歌曲需要一些工作但我太懒了(现在是星期五)

data.test = data.frame(Date = c("9/8/2017 8:30 AM","8/9/2017 8:45 AM", "16/11/2017 9:00 AM", "11/16/2017 9:15 AM", "11/16/2017 9:30 AM"), Observed = c(100, 23, 291, 30, 45))

Date1<-
as.POSIXct(data.test$Date, format="%m/%d/%Y %H:%M %p") # search for format1
Date2<-
as.POSIXct(data.test$Date, format="%d/%m/%Y %H:%M %p") # search for format2

# Replace data.test Date Column with Date1, leaving NAs
data.test$Date<-Date1


#Check most plausible date format.
for(i in 1:length(Date1)){
  if(is.na(Date1[i])==F  && is.na(Date2[i])==F && i!= 1){
    print(paste("row",i , "ambigious format"))
      if(month(Date1[i-1])==month(Date1[i])){
         print("Date Estimated from mm/dd/YYYY format based on previous")
      }else{
         Date1[i]<-Date2[i]
         print("Date Estimated from dd/mm/YYYY format based on previous")
}
}else{}
}



# Replace NAs in data.test with index from Date2, line up
data.test$Date[is.na(data.test$Date)] <- Date2[is.na(data.test$Date)]

> data.test
                 Date Observed
1 2017-09-08 08:30:00      100
2 2017-09-08 08:45:00       23
3 2017-11-16 09:00:00      291
4 2017-11-16 09:15:00       30
5 2017-11-16 09:30:00       45

【讨论】:

  • 如果日期和月份都小于 13,则不会成功。需要知道位置以进行准确的换位定位。
  • @42- 很好的观察,试图用一个非常奇怪的解决方法来解决这个问题。至少很有趣,哈哈。
  • 您使用基于尾随结果的所谓预测解析似乎很有趣。
猜你喜欢
  • 1970-01-01
  • 2023-03-11
  • 2018-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-14
  • 1970-01-01
相关资源
最近更新 更多