2011-05-19 4 views
8

У меня есть несколько файлов данных, которые выглядят следующим образом:Как создать «NA» для отсутствующих данных во временном ряду

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 

Иногда не хватает данных, но у меня нет Nas, строки просто не существует. Мне нужно создать 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 или без него)?

благодаря

+0

Вы имеете в виду, что ваши данные не содержат строк для некоторых дат? И как это относится к вашим первым двум столбцам (X и код)? –

ответ

19

seq функция имеет некоторые интересные функции, которые вы можете использовать, чтобы легко создавать полную последовательность дат. Например, следующий код может быть использован для создания последовательности дат, начиная с 25 апреля:

Edit: Эта функция описана в ?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 создать Набор данные НСБА:

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 
+2

+1 для прохладного недокументированного трюка. И снова: it_is_ documented:? Seq.Date (-: –

+1

@Nick Спасибо, что показали мне, где найти документы. Я обнаружил эту функцию пять минут назад в списках рассылки R, используя мою любимую поисковую систему, но не смог найти любую ссылку на это в разделе: – Andrie

+0

+1 Отличное решение. – ZnArK

4

В пакете зоопарка «регулярный» означает, что ряд равномерно разнесены, за исключением, возможно, для некоторых недостающих записей. Класс zooreg в пакете зоопарка специально предназначен для этого типа серий. Заметим, что множество всех регулярных рядов включает множество всех одинаково разнесенных рядов, но строго больше.

Функция is.regular проверяет, является ли данная серия регулярной. То есть, существует ли серия, позволяющая сделать ее равной разнесенной, если вставлять NA для отсутствующих записей?

Что касается вашего последнего вопроса, то это часто задаваемые вопросы. См FAQ # 13 в зоопарке FAQ доступный из zoo CRAN page или из R через:

vignette("zoo-faq") 

Также в FAQ # 13 есть некоторый иллюстративный код.

2

Первое, что нужно отметить, это то, что 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 
+0

функции timeBasedSeq повторяют некоторые из дней, которые он создает! Что вызывает проблемы с зоопарком, потому что «записи индекса в« order.by »не уникальны». например, timeBasedSeq ("19860601/19861231") создаст ... "1986-10-25" "1986-10-26" "1986-10-26" "1986-10-27" ... как я могу избежать что? – sbg

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.

Смежные вопросы