10

我有几个看起来像这样的数据文件:

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 的方法(有或没有 zoo 包)?

谢谢

4

4 回答 4

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"

现在使用相同的原理生成一些带有“缺失”行的数据,方法是每隔 2 天生成一次序列:

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
于 2011-05-19T13:07:10.443 回答
4

在 zoo 包中,“常规”意味着该系列是等距的,除了可能缺少一些条目。zoo 包中的zooreg类专门针对该类型的系列。请注意,所有常规系列的集合包括所有等间距系列的集合,但严格来说更大。

is.regular函数检查给定的序列是否是规则的。也就是说,如果为丢失的条目插入 NA,该系列是否可以使其等间距?

关于你的最后一个问题,它是一个常见问题解答。请参阅动物园常见问题解答中的常见问题解答 #13,可从zoo CRAN 页面或 R 中通过以下方式获得:

vignette("zoo-faq") 

同样在 FAQ #13 中有一些说明性代码。

于 2011-05-19T12:53:55.507 回答
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
于 2011-05-19T13:05:51.723 回答
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.

于 2016-07-13T18:20:47.817 回答