我有几个数据文件,如下所示:
X code year month day pp
1 4515 1953 6 1 0
2 4515 1953 6 2 0
3 4515 1953 6 3 0
4 4515 1953 6 4 0
5 4515 1953 6 5 3.5
有时会丢失数据,但我没有NA,行根本就不存在。我需要在数据丢失时创建NA。我虽然可以通过将其转换为动物园对象并检查严格的规律性来确定何时发生(我之前从未使用过动物园),但我使用以下代码:
z.date<-paste(CET$year, CET$month, CET$day, sep="/")
z <- read.zoo(CET, order.by= z.date )
reg<-is.regular(z, strict = TRUE)
但答案总是如此!
谁能告诉我为什么不工作?或者甚至更好,告诉我一种在数据丢失时创建NA的方法(有或没有动物园包)?
感谢
答案 0 :(得分:21)
seq
函数有一些有趣的功能,您可以使用它们轻松生成完整的日期序列。例如,以下代码可用于生成从4月25日开始的一系列日期:
修改:?seq.Date
start = as.Date("2011/04/25")
full <- seq(start, by='1 day', length=15)
full
[1] "2011-04-25" "2011-04-26" "2011-04-27" "2011-04-28" "2011-04-29"
[6] "2011-04-30" "2011-05-01" "2011-05-02" "2011-05-03" "2011-05-04"
[11] "2011-05-05" "2011-05-06" "2011-05-07" "2011-05-08" "2011-05-09"
现在使用相同的原理通过每隔第二天生成序列来生成一些“缺失”行的数据:
partial <- data.frame(
date=seq(start, by='2 day', length=6),
value=1:6
)
partial
date value
1 2011-04-25 1
2 2011-04-27 2
3 2011-04-29 3
4 2011-05-01 4
5 2011-05-03 5
6 2011-05-05 6
要回答您的问题,可以使用向量下标或match
函数创建具有NA的数据集:
with(partial, value[match(full, date)])
[1] 1 NA 2 NA 3 NA 4 NA 5 NA 6 NA NA NA NA
将此结果与原始完整数据合并:
data.frame(Date=full, value=with(partial, value[match(full, date)]))
Date value
1 2011-04-25 1
2 2011-04-26 NA
3 2011-04-27 2
4 2011-04-28 NA
5 2011-04-29 3
6 2011-04-30 NA
7 2011-05-01 4
8 2011-05-02 NA
9 2011-05-03 5
10 2011-05-04 NA
11 2011-05-05 6
12 2011-05-06 NA
13 2011-05-07 NA
14 2011-05-08 NA
15 2011-05-09 NA
答案 1 :(得分:4)
在动物园包中,“常规”表示系列间隔相等,但可能缺少一些条目。 zoo包中的zooreg
类专门用于该类型的系列。请注意,所有常规系列的集合包括所有等间距系列的集合,但严格地说更大。
is.regular
函数检查给定系列是否是常规的。也就是说,如果为缺失的条目插入了NA,该系列是否可以使其间隔相等?
关于你的上一个问题,它是一个FAQ。请参阅动物园常见问题解答中的常见问题解答#13,可从zoo CRAN page或通过以下方式获取:
vignette("zoo-faq")
同样在FAQ#13中有一些说明性代码。
答案 2 :(得分:3)
首先要注意的是z.date
是字符,而不是日期。
以下是使用xts(动物园的子类)解决问题的方法。
# remove the third obs from sample data
CET <- CET[-3,]
# create an actual Date column in CET
CET$date <- as.Date(with(CET, paste(year, month, day, sep="-")))
# create an xts object using 'date' column
x <- xts(CET[,c("code","pp")], CET$date)
# now merge 'x' with a regular date sequence spanning the start/end of 'x'
X <- merge(x, timeBasedSeq(paste(start(x), end(x), sep="::")))
X
# code pp
# 1953-06-01 4515 0.0
# 1953-06-02 4515 0.0
# 1953-06-03 NA NA
# 1953-06-04 4515 0.0
# 1953-06-05 4515 3.5
答案 3 :(得分:0)
我不得不用月度时间序列处理类似的问题。我是通过时间变量直接加入两个data.table
/ data.frame
来完成的。我的观点是时间序列也是一种数据集。因此,您还可以以常规方式将任何时间序列作为常规数据集进行操作。这是我的解决方案:
library(zoo)
(full <- data.table(yrAndMo = as.yearmon(seq(as.Date('2008-01-01'), by = '1 month', length = someLength))))
# the full time horizon that you want to have
# yrAndMo
# 1: Jan 2008
# 2: Feb 2008
# 3: Mar 2008
# 4: Apr 2008
# 5: May 2008
# ---
# 98: Feb 2016
# 99: Mar 2016
# 100: Apr 2016
# 101: May 2016
# 102: Jun 2016
exampleDat # the actually data you want to append to the full time horizon
# yrAndMo someValue
# 1 Mar 2010 7500
# 2 Jun 2010 1115
# 3 Mar 2011 2726
# 4 Apr 2011 1865
# 5 Nov 2011 1695
# 6 Dec 2012 10000
# 7 Mar 2016 1000
library(plyr)
join(full, exampleDat, by = 'yrAndMo', type = "left")
# yrAndMo someValue
# 1: Jan 2008 NA
# 2: Feb 2008 NA
# 3: Mar 2008 NA
# 4: Apr 2008 NA
# 5: May 2008 NA
# ---
# 98: Feb 2016 NA
# 99: Mar 2016 1000
# 100: Apr 2016 NA
# 101: May 2016 NA
# 102: Jun 2016 NA
之后,您可以轻松地将数据集的类更改回您想要的任何类型的时间序列。我更喜欢read.zoo
。