【发布时间】:2012-01-22 14:23:48
【问题描述】:
R:我如何填充数据框的行,其中每一行代表一天,每年都有一个共同的值?
我有一个数据框,其中包含一个日期列、一个价格列以及从这两列派生的各种其他列。其中一列计算给定年份中每一天的价格从该年初开始的百分比变化(这与之前的问题有关)。
我想添加一个列,其中包含给定年份的每一天,该年全年价格的百分比变化。因此,如果价格从 2009 年的第一天到最后一天上涨 10%,则 2009 年所有天数的列应保持 10%(或 0.1)的值。如果价格在 2010 年的第一天和最后一天之间下跌了 2%,则 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 行,每年一个,而用于派生这 4 行的每日数据的数据框中大约有 800 个 - 你会得到不匹配。
使用 for 循环从数据框的最后一行开始并向上移动 daythisyear 列来实现这一点很简单(如果当前行上的 daythisyear 大于下面行上的 daythisyear,则您可以更改年,因此从该行中获取新值以在要添加的列中使用等)。尽管如此,我确信必须有一种使用 apply 函数或 ddply 的 R-口语化方法,到目前为止我一直刻意避免处理。所以我的问题是:
问。如何计算列值的年度变化,然后将该值作为新列插入该年的每一行?
【问题讨论】:
-
不确定我是否理解你的问题,但如果我理解了,
head( merge( df, df.yr, by = "year" ) )可能会给你想要的吗? -
vaettchen,感谢您的建议。这似乎也有效,并且向我展示了我以前没有考虑过的“合并”的一面。
标签: r vectorization plyr