我正在尝试编写一个函数,它使用数据帧的名称、保存时间序列数据的名称以及该数据帧中的列的名称作为参数。该函数对该数据执行各种操作,其中之一是在一列中添加每年运行的总计。我在用plyr。
当我用ddply和累计直接使用列的名称时,我没有问题:
require(plyr)
df <- data.frame(date = seq(as.Date("2007/1/1"),
by = "month",
length.out = 60),
sales = runif(60, min = 700, max = 1200))
df$year <- as.numeric(format(as.Date(df$date), format="%Y"))
df <- ddply(df, .(year), transform,
cum_sales = (cumsum(as.numeric(sales))))
这一切都很好,但最终目标是能够将列名传递给这个函数。当我试图使用一个变量代替列名时,它不像我预期的那样工作:
mycol <- "sales"
df[mycol]
df <- ddply(df, .(year), transform,
cum_value2 = cumsum(as.numeric(df[mycol])))
我以为我知道如何用名字访问列。这让我很担心,因为它表明我对索引和提取的基本知识不太了解。我认为,以这种方式提及列名是一种普遍的需要。
我有两个问题。
我做错了什么呢?我misunderstood?
提亚
发布于 2012-01-15 03:15:34
用于ddply的参数是表达式,这些表达式是在原始数据帧被分割成的每个部分的上下文中计算的。您的dfmyval处理整个数据帧,因此不能将其传递为-is(顺便说一下,为什么需要那些as.numeric(as.character()) --它们是完全无用的)。
最简单的方法是编写您自己的函数,它将完成内部的所有操作,并将列名向下传递。
df <- ddply(df,
.(year),
.fun = function(x, colname) transform(x, cum_sales = cumsum(x[,colname])),
colname = "sales")
发布于 2012-01-15 02:57:35
问题是,ddply
希望它的最后一个参数是表达式,这些表达式将在data.frame的块上进行计算(在您的示例中,每年都是这样)。如果使用df[myval]
,就会得到整个data.frame,而不是年度块。
下面的方法可以工作,但并不是很优雅:我将表达式构建为字符串,然后使用eval(parse(...))
进行转换。
ddply( df, .(year), transform,
cum_value2 = eval(parse( text =
sprintf( "cumsum(as.numeric(as.character(%s)))", mycol )
))
)
https://stackoverflow.com/questions/8869005
复制