我有一个约有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
在我的数据集中,日期是字符,而其余的行是数字。
答案 0 :(得分:1)
您说您知道需要进行更改的位置(大概是行号的范围),但是您没有在示例中给出这些位置,可能是因为它很明显。但是在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
答案 1 :(得分: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
答案 2 :(得分:0)
这是一个有趣的尝试。假设您的第一个观察结果采用正确的格式,则需要编写一些代码以根据日期应该在哪个月份检查最合理的日期格式。它如何处理几个月的变化我还不确定。
这种想法是,只要第一个观察结果正确,它将以正确的格式继续进行,直到出现不明确的日期。到那时,它会根据先前观察的正确月份检查。如果它们匹配,则可以正确预测当前的歧义观测值;否则,它将选择其他格式。再说一次,几个月的切换和模糊的打击需要一些工作,但我太懒了(今天是星期五)
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