2012-01-22 5 views
0

R: как я могу заполнить строки фрейма данных, в которых каждая строка представляет день, с одним общим значением за каждый год?Как я могу заполнить строки кадра данных R, в которых каждая строка представляет день, с одним общим значением за каждый день года?

У меня есть кадр данных, состоящий из столбца даты, столбца цены, а затем различных других столбцов, полученных из этих двух столбцов. Один из столбцов рассчитывает за каждый день в данном году процентное изменение цены с начала этого года (это связано с более ранним вопросом).

Я хочу добавить столбец, который хранит для каждого дня определенного года процентное изменение цены за весь этот год. Итак, если цена повысилась на 10% с первого по последний день 2009 года, столбец за все дни 2009 года должен иметь значение 10% (или 0,1). Если цена упала на 2% между первым и последним днями 2010 года, столбец за каждый день 2010 года должен содержать значение -0,02 и так далее.

код у меня до сих пор:

require(lubridate) 
require(plyr) 
# generate data 
set.seed(12345) 
df <- data.frame(date=seq(as.Date("2009/1/1"), by="day", length.out=1115),price=runif(1115, min=100, max=200)) 
# remove weekend days 
df <- df[!(weekdays(as.Date(df$date)) %in% c('Saturday','Sunday')),] 
# add some columns for later 
df$year <- as.numeric(format(as.Date(df$date), format="%Y")) 
df$month <- as.numeric(format(as.Date(df$date), format="%m")) 
df$day <- as.numeric(format(as.Date(df$date), format="%d")) 
df$daythisyear <- as.numeric(format(as.Date(df$date), format="%j")) 
df <- transform(df, doy = as.Date(paste(2000, month, day, sep="/"))) 
df <- ddply(df, .(year), transform, pctchg = ((price/price[1])-1)) 

Я понимаю, что я могу получить годовое изменение (в годовом исчислении) с использованием другого кадра данных, что-то вроде этого:

df.yr <- ddply(df, .(year), function(x) (x[nrow(x),2]/x[1,2])-1) 

... но я не могу понять, как добавить цифры за годы к столбцу в существующем фрейме данных, особенно учитывая, что (если вы работаете с данными за 4 года) есть только 4 строки, один за каждый год, по сравнению с около 800 в кадре данных ежедневных данных, используемых для получения этих 4 строк - вы получаете mismatc час

Прямо использовать цикл for, начиная с последней строки кадра данных, и возвращать назад этот столбец daythisyear для достижения этого (если daythisyear в текущей строке больше, чем в течение дня в строке ниже, у вас есть изменение в год, поэтому возьмите новое значение из этой строки для использования в добавляемом столбце и т. д.). Тем не менее, я уверен, что должен быть более R-разговорный подход с использованием функции приложения или ddply, который я до сих пор старательно избегал заниматься. Поэтому мой вопрос:

В. Как рассчитать годовое изменение значения столбца и затем вставить это значение в качестве нового столбца в каждую строку за этот год?

+0

Не уверен, понимаю ли я свой вопрос права, но если я делаю, 'головы (слияние (ДФ, df.yr, по =«год»))' может дать то, что вы хотите? – vaettchen

+0

vaettchen, спасибо за это предложение. Это также, похоже, работает и показало мне сторону «слияния», которую я раньше не рассматривал. – SlowLearner

ответ

2

Я еще не преобразован в пользователя ddply, предпочитая вместо этого использовать ave, когда это очевидное решение. Я подозреваю, что этот код будет переводить через:

df$pctYrChng <- ave(df$price, df$year, FUN=function(x) tail(x,1)/head(x,1) - 1) 
unique(df$pctYrChng) 
#[1] -0.03259032 -0.05781901 0.35932519 0.04246669 
+0

Кажется, что это работает так, как просили и с приятной простотой. Я смутно знал о «аве», но сам не использовал. Если это можно сделать легко в базе R, тогда я не чувствую необходимости искать в другом месте! Спасибо, Дэн – SlowLearner

+0

Я не был уверен, что знаю, хотите ли вы сменить YTD, или если вы хотите изменить с day.one на день.last. Я дал вам решение для второго варианта, но решение для первого просто включит замену 'x' для' tail (x, 1) ' –