在R中汇总聚合内的列

52 aggregate r rename

我知道在汇总数据后我可以*重新命名列:

blubb <- aggregate(dat$two ~ dat$one, ...)
colnames(blubb) <- c("One", "Two")
Run Code Online (Sandbox Code Playgroud)

没有错.但有没有办法一次性聚合和命名列?有点像:

blubb <- aggregate( ... , cols = c("One", "Two"))
Run Code Online (Sandbox Code Playgroud)

以某种方式捕获原始列名称并且如下所示,这将是特别好的(并且防止错误):

blubb <- aggregate( ... , cols = c(name_of_dat$one, name_of_dat$two."_Mean"))
Run Code Online (Sandbox Code Playgroud)

A5C*_*2T1 69

您可以使用setNames如下:

blubb <- setNames(aggregate(dat$two ~ dat$one, ...), c("One", "Two"))
Run Code Online (Sandbox Code Playgroud)

或者,您可以绕过光滑的公式方法,并使用如下语法:

blubb <- aggregate(list(One = dat$one), list(Two = dat$two), ...)
Run Code Online (Sandbox Code Playgroud)

更新

此更新只是帮助您开始自己推导解决方案.

如果你检查代码stats:::aggregate.formula,你会看到以下几行:

if (is.matrix(mf[[1L]])) {
    lhs <- as.data.frame(mf[[1L]])
    names(lhs) <- as.character(m[[2L]][[2L]])[-1L]
    aggregate.data.frame(lhs, mf[-1L], FUN = FUN, ...)
}
else aggregate.data.frame(mf[1L], mf[-1L], FUN = FUN, ...)
Run Code Online (Sandbox Code Playgroud)

如果您要做的只是将函数名称附加到已聚合的变量,也许您可​​以将其更改为:

if (is.matrix(mf[[1L]])) {
  lhs <- as.data.frame(mf[[1L]])
  names(lhs) <- as.character(m[[2L]][[2L]])[-1L]
  myOut <- aggregate.data.frame(lhs, mf[-1L], FUN = FUN, ...)
  colnames(myOut) <- c(names(mf[-1L]), 
                       paste(names(lhs), deparse(substitute(FUN)), sep = "."))
}
else {
  myOut <- aggregate.data.frame(mf[1L], mf[-1L], FUN = FUN, ...)
  colnames(myOut) <- c(names(mf[-1L]), 
                       paste(strsplit(gsub("cbind\\(|\\)|\\s", "", 
                                           names(mf[1L])), ",")[[1]],
                             deparse(substitute(FUN)), sep = "."))
} 
myOut
Run Code Online (Sandbox Code Playgroud)

这基本上捕获了FUN使用输入的值deparse(substitute(FUN)),因此您可以修改函数以接受自定义后缀,甚至可能是后缀的向量.有些工作可能会有所改善,但我不打算这样做!

这是一个应用了这个概念的Gist,创建了一个名为"myAgg"的函数.

以下是结果列名称的一些示例输出:

> names(myAgg(weight ~ feed, data = chickwts, mean))
[1] "feed"        "weight.mean"
> names(myAgg(breaks ~ wool + tension, data = warpbreaks, sum))
[1] "wool"       "tension"    "breaks.sum"
> names(myAgg(weight ~ feed, data = chickwts, FUN = function(x) mean(x^2)))
[1] "feed"                         "weight.function(x) mean(x^2)"
Run Code Online (Sandbox Code Playgroud)

请注意,只有聚合变量名称会更改.但请注意,如果你使用自定义函数,你最终会得到一个非常奇怪的列名!

  • 我喜欢另一种选择:-) (2认同)

GKi*_*GKi 11

如果您更喜欢编写聚合,因为formula文档显示了cbind. 并cbind允许您命名其参数,这些参数由aggregate.

aggregate(cbind(SLength = Sepal.Length) ~ cbind(Type = Species),
  data = iris, mean)
#  Type SLength
#1    1   5.006
#2    2   5.936
#3    3   6.588
Run Code Online (Sandbox Code Playgroud)

cbind替换factors为它们的内部代码,并且当在其右侧使用时,~会将调用保留cbind在结果中。transform为了避免这种情况,可以使用或在输入数据集中给出新名称within

aggregate(SLength ~ Type, transform(iris, SLength = Sepal.Length,
   Type = Species), mean)
#        Type SLength
#1     setosa   5.006
#2 versicolor   5.936
#3  virginica   6.588
Run Code Online (Sandbox Code Playgroud)

或者

aggregate(cbind(SLength = Sepal.Length) ~ Type, transform(iris, Type = Species),
  mean)
#        Type SLength
#1     setosa   5.006
#2 versicolor   5.936
#3  virginica   6.588
Run Code Online (Sandbox Code Playgroud)

cbind使用或data.frame比较的优点list是并非所有列都需要指定(新)名称。通过多个分组因子聚合多个列可以如下完成:

aggregate(cbind("Miles/gallon" = mpg, Weight = wt, hp) ~ Cylinders + Carburetors
          + gear, transform(mtcars, Cylinders = cyl, Carburetors = carb), mean)
#   Cylinders Carburetors gear Miles/gallon  Weight    hp
#1          4           1    3        21.50 2.46500  97.0
#2          6           1    3        19.75 3.33750 107.5
#...
Run Code Online (Sandbox Code Playgroud)

如果您想使用多个功能:

aggregate(cbind(cases=ncases, ncontrols) ~ alc + tobgp, transform(esoph,
  alc=alcgp), FUN = function(x) c("mean" = mean(x), "median" = median(x)))
#         alc    tobgp cases.mean cases.median ncontrols.mean ncontrols.median
#1  0-39g/day 0-9g/day  1.5000000    1.0000000      42.000000        44.000000
#2      40-79 0-9g/day  5.6666667    4.0000000      24.166667        29.000000
#...
Run Code Online (Sandbox Code Playgroud)

它将使用的聚合函数添加到 colname 中。

聚合mpg重命名为Miles/gallon和 hp 的一些示例通过cyl重命名为Cylindersgearusingmtcars产生:

#  Cylinders gear Miles/gallon       hp
#1         4    3       21.500  97.0000
#2         6    3       19.750 107.5000
#3         8    3       15.050 194.1667
#4         4    4       26.925  76.0000
#5         6    4       19.750 116.5000
#6         4    5       28.200 102.0000
#7         6    5       19.700 175.0000
#8         8    5       15.400 299.5000
Run Code Online (Sandbox Code Playgroud)
aggregate(cbind("Miles/gallon" = mpg, hp) ~ Cylinders + gear,
          transform(mtcars, Cylinders = cyl, Carburetors = carb), mean)

with(mtcars, aggregate(cbind("Miles/gallon" = mpg, hp),
                       data.frame(Cylinders = cyl, gear), mean))

with(mtcars, aggregate(data.frame("Miles/gallon" = mpg, hp),
                       data.frame(Cylinders = cyl, gear), mean))
Run Code Online (Sandbox Code Playgroud)


orv*_*son 10

你的第一个问题的答案是肯定的.您当然可以在聚合函数中包含列名.使用上面示例中的名称:

blubb <- aggregate(dat,list(One=dat$One,Two=dat$Two),sum)

我喜欢有关可能自动提取原始列名称的部分.如果我搞清楚,我会发布它.

  • 从几个月前开始,你的回答已经在我的答案中了.... (7认同)
  • 以及如何更改由函数“sum”产生的列的名称?现在它只是`x` (3认同)