#r #plyr
#r #plyr
Вопрос:
У меня есть набор данных, который включает обращения по годам и месяцам. Не хватает нескольких месяцев, и я хотел бы создать строки с нулевым количеством обращений за эти месяцы.
Вот пример и мой текущий подход грубой силы. Спасибо за любые указания. Очевидно, я новичок в этом.
# fake data
library(plyr)
rm(FakeData)
FakeData <- data.frame(DischargeYear=c(rep(2010, 7), rep(2011,7)),
DischargeMonth=c(1:7, 3:9),
Cases=trunc(rnorm(14, mean=100, sd=20)))
# FakeData is missing data for some year/months
FakeData
# Brute force attempt to add rows with 0 and then total
for(i in 1:12){
for(j in 1:length(unique(FakeData$DischargeYear))){
FakeData <- rbind(FakeData, data.frame(
DischargeYear=unique(FakeData$DischargeYear)[j],
DischargeMonth=i,
Cases=0))
}
}
FakeData <- ddply(FakeData, c("DischargeYear","DischargeMonth"), summarise, Cases=sum(Cases))
# FakeData now has every year/month represented
FakeData
Ответ №1:
Используя ваш FakeData
фрейм данных, попробуйте это:
# Create all combinations of months and years
allMonths <- expand.grid(DischargeMonth=1:12, DischargeYear=2010:2011)
# Keep all month-year combinations (all.x=TRUE) and add in 'Cases' from FakeData
allData <- merge(allMonths, FakeData, all.x=TRUE)
# 'allData' contains 'NA' for missing values. Set them to 0.
allData[is.na(allData)] <- 0
# Print results
allData
Комментарии:
1. Спасибо, я знал, что должен быть способ. Просто для полноты картины мне нужно было бы заменить NAs на 0, поэтому я думаю, что ответ будет таким: FakeData <- merge(allMonths, FakeData, all.x= TRUE) FakeData$Cases[is.na (FakeData$Cases)] <- 0
Ответ №2:
Другим решением было бы использовать cast
из reshape
пакета.
require(reshape)
cast(Fakedata, DischargeYear DischargeMonth ~ ., add.missing = TRUE, fill = 0)
Обратите внимание, что он добавляет только 0 для отсутствующих комбинаций в данных, месяцев 8, 9 для 2010 года и месяцев 1 и 2 для 2011 года. Чтобы убедиться, что у вас есть все месяцы 1: 12, вы можете изменить определение DischargeMonth на коэффициент с уровнями 1: 12, используя
FakeData = transform(FakeData,
DischargeMonth = factor(DischargeMonth, levels = 1:12))
Комментарии:
1. Рамнатх, это очень полезно. Я немного ошеломлен выбором между reshape, ? reshape2, plyr, все из которых кажутся похожими. Может быть, мне стоит выбрать что-то одно и попытаться хорошо его выучить?
Ответ №3:
Вот решение зоопарка. Обратите внимание, что в zoo FAQ # 13 обсуждается формирование сетки, g
. Также мы преобразуем год и месяц в "yearmon"
переменную класса, которая представлена как год плюс дробный месяц (0 = январь, 1/12 = февраль, 2/12 = март и т.д.)
library(zoo)
# create zoo object with yearmon index
DF <- FakeData
z <- zoo(DF[,3], yearmon(DF[,1] (DF[,2]-1)/12))
# create grid g. Merge zero width zoo object based on it. Fill NAs with 0s.
g <- seq(start(z), end(z), 1/12)
z0 <- na.fill(merge(z, zoo(, g)), fill = 0)
что дает
> z0
Jan 2010 Feb 2010 Mar 2010 Apr 2010 May 2010 Jun 2010
149 113 110 99 110 96
Jul 2010 Aug 2010 Sep 2010 Oct 2010 Nov 2010 Dec 2010
108 0 0 0 0 0
Jan 2011 Feb 2011 Mar 2011 Apr 2011 May 2011 Jun 2011
0 0 91 72 119 130
Jul 2011 Aug 2011 Sep 2011
93 74 112
или преобразование в "ts"
класс:
> as.ts(z0)
Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
2010 149 113 110 99 110 96 108 0 0 0 0 0
2011 0 0 91 72 119 130 93 74 112
Обратите внимание, что если z
это объект zoo, то coredata(z)
это его данные и time(z)
значения его индекса.
Комментарии:
1. Интересно, хотя на данный момент zoo кажется мне излишним.
2. @Джим, Но действительно ли это конец вашего анализа? В противном случае все последующие процессы могут извлечь выгоду из наличия структуры данных, которая лучше подходит для решения проблемы.