问题描述
我有一个数据集,如下所示:
I have a dataset as follows:
19/9/19971997/9/221997年23月9日1997年9月24日1997年9月25日1997年9月26日1997年9月29日1997/9/30
19/9/199722/9/199723/9/199724/9/199725/9/199726/9/199729/9/199730/9/1997
3544035471354993559135621356523568335713
3544035471354993559135621356523568335713
13/10/19971997年10月14日15/10/19971997年10月16日1997年10月17日1997年10月20日1997年10月21日1997年10月22日1997年10月23日1997年10月24日1997年10月27日1997年10月28日1997年10月29日1997年10月30日1997年10月31日
13/10/199714/10/199715/10/199716/10/199717/10/199720/10/199721/10/199722/10/199723/10/199724/10/199727/10/199728/10/199729/10/199730/10/199731/10/1997
3550035531355613559235622357143574535775
3550035531355613559235622357143574535775
1997年11月13日1997年11月14日1997年11月17日1997年11月18日1997/11/191997年11月20日1997年11月21日1997年11月24日...
13/11/199714/11/199717/11/199718/11/199719/11/199720/11/199721/11/199724/11/1997 ...
此处应包含的数据(用于按要求复制)1997年9月19日1997/9/221997年23月9日1997年9月24日1997年9月25日1997年9月26日1997年9月29日1997年9月30日1997年10月1日1997年10月2日1997年10月3日10/06/19971997年10月7日1997年10月8日1997年10月9日1997/10/101997年10月13日1997年10月14日15/10/19971997年10月16日1997年10月17日1997年10月20日1997年10月21日1997年10月22日1997年10月23日1997年10月24日1997年10月27日1997年10月28日1997年10月29日1997年10月30日1997年10月31日1997年11月3日1997年11月4日1997年11月5日11/06/19971997年11月7日1997年11月10日1997/11/111997年11月12日1997年11月13日1997年11月14日1997年11月17日1997年11月18日1997/11/191997年11月20日1997年11月21日1997年11月24日
The Data that should be here are (for reproduction as requested)19/9/199722/9/199723/9/199724/9/199725/9/199726/9/199729/9/199730/9/199710/01/199710/02/199710/03/199710/06/199710/07/199710/08/199710/09/199710/10/199713/10/199714/10/199715/10/199716/10/199717/10/199720/10/199721/10/199722/10/199723/10/199724/10/199727/10/199728/10/199729/10/199730/10/199731/10/199711/03/199711/04/199711/05/199711/06/199711/07/199711/10/199711/11/199711/12/199713/11/199714/11/199717/11/199718/11/199719/11/199720/11/199721/11/199724/11/1997
我有5149行日期,其中日期位置有数字.我尝试使用此方法来修复丢失的日期:修订前尝试1:
I have 5,149 rows of dates where there are numbers in places of dates. I tried fixing the missing dates with this:ATTEMPT 1 BEFORE REVISION:
rm (list = ls(all=TRUE))
graphics.off()
library(readxl)
Dates <- read_excel("F:/OneDrive - University of Tasmania/Mardi Meetings/Dataset/Dates.xlsx")
x<-Dates[,1]
library(date)
library(datetime)
ans <- Reduce(function(prev, curr) {
f1 <- as.Date(curr, "%d/%m/%Y")
f2 <- as.Date(curr, "%m/%d/%Y")
if (is.na(f1)) return(f2)
if (is.na(f2)) return(f1)
if (prev < f1 && prev < f2) return(min(f1, f2))
if (prev < f1) return(f1)
if (prev < f2) return(f2)
}, x[-1], init=as.Date(x[1], "%d/%m/%Y"), accumulate=TRUE)
as.Date(ans, origin="1970-01-01")
但是我遇到了以下错误:
But I am getting the following error:
+ }, x[-1], init=as.Date(x[1], "%d/%m/%Y"), accumulate=TRUE)
Error in Reduce(function(prev, curr) { : object 'x' not found
>
> as.Date(ans, origin="1970-01-01")
Error in as.Date(ans, origin = "1970-01-01") : object 'ans' not found
任何建议将不胜感激.
根据建议,我在修订后尝试了代码尝试2
OK AS PER ADVICE I REVISED THE CODE ATTEMPT 2 AFTER REVISION
> rm (list = ls(all=TRUE))
> graphics.off()
> library(readxl)
> Dates <- read_excel("F:/OneDrive - University of Tasmania/Mardi Meetings/Dataset/Dates.xlsx")
> dput(head(Dates))
structure(list(Date = c("33274", "33302", "33394", "33424", "33455",
"33486")), row.names = c(NA, -6L), class = c("tbl_df", "tbl",
"data.frame"))
> x<-Dates[[1]]
> library(date)
> library(datetime)
Attaching package: ‘datetime’
The following object is masked from ‘package:date’:
as.date
> dates <- as.Date(x, format="%d/%m/%Y")
> dput(head(dates))
structure(c(NA_real_, NA_real_, NA_real_, NA_real_, NA_real_,
NA_real_), class = "Date")
> head(dates,10)
[1] NA NA NA NA NA NA NA
[8] "1991-05-13" "1991-05-14" "1991-05-15"
As you can see I have lost the corrupted dates completely
今天28号,我再次尝试了
Today on 28th I tried again
> rm (list = ls(all=TRUE))
> graphics.off()
> library(readxl)
> Dates <- read_excel("F:/OneDrive - University of Tasmania/Mardi Meetings/Dataset/Dates.xlsx")
> x<-Dates[[1]]
>
> library(date)
> library(datetime)
Attaching package: ‘datetime’
The following object is masked from ‘package:date’:
as.date
> formats <- c("%m/%d/%Y", "%d/%m/%Y", "%Y/%m/%d")
> dates <- as.Date(rep(NA, length(x)))
> for (fmt in formats) {
+ nas <- is.na(dates)
+ dates[nas] <- as.Date(as.integer(x[nas], format=fmt))
+ }
Error in as.Date.numeric(as.integer(x[nas], format = fmt)) :
'origin' must be supplied
In addition: Warning message:
In as.Date(as.integer(x[nas], format = fmt)) : NAs introduced by coercion
> dates <- as.Date(x, format="%d/%m/%Y")
> head(dates)
[1] NA NA NA NA NA NA
> head(dates, 10)
[1] NA NA NA NA NA NA NA
[8] "1991-05-13" "1991-05-14" "1991-05-15"
推荐答案
您不需要加载任何软件包,也不需要使用 Reduce
,因为我们在此处使用的功能是自然的向量化".
You need none of the packages you've loaded, nor do you need to use Reduce
, as functions we're using here are naturally "vectorized".
这是您的数据示例.(一个很好的问题包括诸如容易这样的复制格式的数据.)
Here's a sample of your data. (A good question includes data in an easily copied format such as this.)
x <- c("19/9/1997", "22/9/1997", "23/9/1997", "24/9/1997", "25/9/1997",
"26/9/1997", "29/9/1997", "30/9/1997",
"35440", "35471", "35499", "35591", "35621",
"35652", "35683", "35713")
dates <- as.Date(x, format="%d/%m/%Y")
dates
# [1] "1997-09-19" "1997-09-22" "1997-09-23" "1997-09-24" "1997-09-25"
# [6] "1997-09-26" "1997-09-29" "1997-09-30" NA NA
# [11] NA NA NA NA NA
# [16] NA
不足为奇的是,给定 format =%d/%m/%Y"
,下半部分日期无法识别.您在问题中提到了%m/%d/%Y"
的使用,因此我们可以(1)对这种格式进行一次字面的二次遍历(此示例未使用,但是还是与您的工作相关?):
Not surprisingly, the second-half of the dates are not recognized given format="%d/%m/%Y"
. You mentioned the use of "%m/%d/%Y"
in your question, so we can (1) do a literal second-pass for this format (un-utilized with this example, but still relevant for your work?):
dates[is.na(dates)] <- as.Date(x[is.na(dates)], format="%m/%d/%Y")
其中 [is.na(dates)]
仅适用于未转换的元素.
where [is.na(dates)]
only works on the un-converted elements.
(2)如果我们有多种其他格式,则始终可以使用它们的向量并在它们上循环.(为此,我将重新开始,因为此循环将替换/增强上面的第一步.)
(2) If we have more than one other format, you can always use a vector of them and loop over them. (For this, I'll start over, since this loop would replace/augment the first steps above.)
formats <- c("%m/%d/%Y", "%d/%m/%Y", "%Y/%m/%d")
dates <- as.Date(rep(NA, length(x)))
for (fmt in formats) {
nas <- is.na(dates)
dates[nas] <- as.Date(x[nas], format=fmt)
}
dates
# [1] "1997-09-19" "1997-09-22" "1997-09-23" "1997-09-24" "1997-09-25"
# [6] "1997-09-26" "1997-09-29" "1997-09-30" NA NA
# [11] NA NA NA NA NA
# [16] NA
这仍然给我们留了 NA
s个整数.对于这些,您需要指定 origin =
以便能够弄清楚(以及转换为整数).R通常与"1970-01-01"
的原点一起使用,您可以通过以下方式进行确认
This still leaves us with NA
s for the integer-looking ones. For these you need to specify the origin=
to be able to figure it out (as well as converting to an integer). R typically works with an origin of "1970-01-01"
, which you can confirm with
as.integer(Sys.Date())
# [1] 17787
Sys.Date() - 17787
# [1] "1970-01-01"
但是您的日期似乎起源于"1900-01-01"
,我认为这是Excel的默认日期存储方式(但这并不重要):
but it appears that your dates have an origin of "1900-01-01"
, I think that's Excel's default storage of dates (but it doesn't matter here):
x[9] # the first integer-looking element
# [1] "35440"
dates[1] - as.integer(x[9])
# [1] "1900-09-08"
(我假设您的日期来自相同的相对时间段.)
(I'm assuming that your dates are from the same relative period of time.)
从这里:
nas <- is.na(dates)
dates[nas] <- as.Date(as.integer(x[nas]), origin="1900-01-01")
dates
# [1] "1997-09-19" "1997-09-22" "1997-09-23" "1997-09-24" "1997-09-25"
# [6] "1997-09-26" "1997-09-29" "1997-09-30" "1997-01-12" "1997-02-12"
# [11] "1997-03-12" "1997-06-12" "1997-07-12" "1997-08-12" "1997-09-12"
# [16] "1997-10-12"
(仅处理 NA
个元素的索引相对有效,因为它仅可处理并替换尚未匹配的条目. as.Date
,它仍然会调用它,但是带有长度为0的参数,该函数可以有效地工作.我不认为添加条件条件 if(any(nas))...
会有所帮助,但是如果您需要其他可能更昂贵"的方法,则可以考虑.)
(Working on the indices of only NA
elements is relatively efficient in that it only works on and replaces the not-yet-matched entries. If there is nothing left when it gets to another call to as.Date
, it does still call it but with an argument of length 0, with which the function works rather efficiently. I don't think adding a conditional of if (any(nas)) ...
would help, but if there are further methods you need that might be more "expensive", you can consider it.)
这篇关于如何修复R中的损坏日期?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!