【问题标题】:How can I use variable names to refer to data frame columns with ddply?如何使用变量名通过 ddply 引用数据框列?
【发布时间】:2012-01-15 10:30:28
【问题描述】:

我正在尝试编写一个函数,该函数将保存时间序列数据的数据框的名称和该数据框中的列名称作为参数。该函数对该数据执行各种操作,其中之一是在列中添加每年的运行总计。我正在使用 plyr。

当我直接使用 ddply 和 cumsum 列的名称时,我没有问题:

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])))

我以为我知道如何按名称访问列。这让我很担心,因为它表明我没有理解一些关于索引和提取的基本知识。我原以为以这种方式按名称引用列将是一种常见的需求。

我有两个问题。

  1. 我做错了什么,即我误解了什么?
  2. 有没有更好的方法来解决这个问题,记住函数不会事先知道列的名称?

TIA

【问题讨论】:

    标签: r plyr


    【解决方案1】:

    ddply 的参数是表达式,它们在原始数据帧被分割成的每个部分的上下文中进行评估。您的 df[myval] 处理整个数据框,因此您不能按原样传递它(顺便说一句,您为什么需要那些 as.numeric(as.character()) 东西 - 它们完全没用)。

    最简单的方法是编写自己的函数,该函数将在内部完成所有操作并将列名向下传递,例如

    df <- ddply(df, 
                .(year), 
                .fun = function(x, colname) transform(x, cum_sales = cumsum(x[,colname])), 
                colname = "sales")
    

    【讨论】:

      【解决方案2】:

      问题是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 )
        ))
      )
      

      【讨论】:

      • 感谢文森特 - 我实际上尝试了 eval 和 parse 的组合,但语法错误。这对我来说很清楚。干杯,丹
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-18
      • 1970-01-01
      相关资源
      最近更新 更多