如何在将数据框列动态传递给`aggregate`

时间:2016-12-10 11:41:34

标签: r dataframe aggregate

使用如下数据框

df1 <- data.frame(a=seq(1.1,9.9,1.1), b=seq(0.1,0.9,0.1),
                  c=rev(seq(10.1, 99.9, 11.1)))

我希望b

汇总cols ca

所以我会做这样的事情

aggregate(cbind(b,c) ~ a, data = df1, mean)

这样就可以完成。但是,我想在没有硬编码列名的情况下进行概括,就像在函数中一样。

myAggFunction <- function (df, col_main, col_1, col_2){
    return (aggregate(cbind(df[,col1], df[,col2]) ~ df[,col_main], df, mean))
    }
myAggFunction(df, 1, 2, 3)

我遇到的问题是返回数据框的列名如下所示

 df2[, 1]  V1   V2

如何在返回的数据框中获取原始数据框中的列名?

1 个答案:

答案 0 :(得分:2)

我将假设一般情况,你有多个LHS(左手边)以及多个RHS(右手边)。

使用&#34; data.frame&#34;方法

## S3 method for class 'data.frame'
aggregate(x, by, FUN, ..., simplify = TRUE, drop = TRUE)

如果将对象作为命名列表传递,则会保留名称。因此,请勿使用[, ]访问您的数据框,而应使用[]。您可以将您的功能构建为:

## `LHS` and `RHS` are vectors of column names or numbers giving column positions
fun1 <- function (df, LHS, RHS){
  ## call `aggregate.data.frame`
  aggregate.data.frame(df[LHS], df[RHS], mean)
  }

仍在使用&#34;公式&#34;方法吗

## S3 method for class 'formula'
aggregate(formula, data, FUN, ...,
          subset, na.action = na.omit)

这有点单调乏味,但我们希望通过以下方式构建一个很好的公式:

as.formula( paste(paste0("cbind(", toString(LHS), ")"),
                  paste(RHS, collapse = " + "), sep = " ~ ") )

例如:

LHS <- c("y1", "y2", "y3")
RHS <- c("x1", "x2")
as.formula( paste(paste0("cbind(", toString(LHS), ")"),
                  paste(RHS, collapse = " + "), sep = "~") )
# cbind(y1, y2, y3) ~ x1 + x2

如果您将此公式提供给aggregate,您将获得不错的列名称。

所以构建你的函数:

fun2 <- function (df, LHS, RHS){
  ## ideally, `LHS` and `RHS` should readily be vector of column names
  ## but specifying vector of numeric positions are allowed
  if (is.numeric(LHS)) LHS <- names(df)[LHS]
  if (is.numeric(RHS)) RHS <- names(df)[RHS]
  ## make a formula 
  form <- as.formula( paste(paste0("cbind(", toString(LHS), ")"),
                      paste(RHS, collapse = " + "), sep = "~") )
  ## call `aggregate.formula`
  stats:::aggregate.formula(form, df, mean)
  }

<强>备注

aggregate.data.frame是最好的。 aggregate.formula是一个包装器,会在里面调用model.frame来构建一个数据帧。

我给出了#34;公式&#34;方法作为选项,因为我构造公式的方式对lm等有用。

简单,可重复的示例

set.seed(0)
dat <- data.frame(y1 = rnorm(10), y2 = rnorm(10),
                  x1 = gl(2,5, labels = letters[1:2]))

## "data.frame" method with `fun1`
fun1(dat, 1:2, 3)
#  x1          y1         y2
#1  a  0.79071819 -0.3543499
#2  b -0.07287026 -0.3706127

## "formula" method with `fun2`
fun2(dat, 1:2, 3)
#  x1          y1         y2
#1  a  0.79071819 -0.3543499
#2  b -0.07287026 -0.3706127

fun2(dat, c("y1", "y2"), "x1")
#  x1          y1         y2
#1  a  0.79071819 -0.3543499
#2  b -0.07287026 -0.3706127