1

对于我的问题,我创建了一个虚拟数据框:

    set.seed(007)
 DF <- data.frame(a = rep(LETTERS[1:5], each=2), b = sample(40:49), c = sample(1:10))
 DF
   a  b  c
1  A 49  2
2  A 43  3
3  B 40  7
4  B 47  1
5  C 41  9
6  C 48  8
7  D 45  6
8  D 42  5
9  E 46 10
10 E 44  4

如何在列上使用聚合函数a,例如,对于“A”,计算以下值:49-43 / 2+3?

我开始喜欢:

aggregate(DF, by=list(DF$a), FUN=function(x) {

  ...

})

我遇到的问题是我不知道如何访问我尝试过的 4 个不同的单元格 49、43、2 和 3x[[1]][1]以及类似的东西,但没有让它工作。

4

5 回答 5

4

在内部aggregate,该函数FUN独立应用于数据的每一列。在这里,您想使用一个将两列作为输入的函数,因此,您不能先验地使用aggregate它。

相反,您可以ddplyplyr包中使用:

ddply(DF, "a", summarize, res = (b[1] - b[2]) / sum(c))
#   a        res
# 1 A  1.2000000
# 2 B -0.8750000
# 3 C -0.4117647
# 4 D  0.2727273
# 5 E  0.1428571
于 2012-09-12T10:53:56.910 回答
2

当您聚合时,FUN参数可以是您想要的任何东西。请记住,传递的值将是 a vector(如果 x 是一列)或一点点data.framematrix(如果 x 大于一)。但是,aggregate不允许您访问多列参数的列。例如。

aggregate( . ~ a, data = DF, FUN = function(x) diff(x[,1]) / sum(x[,2]) )

即使我使用了.(它采用了我在其他地方没有使用的所有 DF 列),它也会失败并出现错误。要查看aggregate在那里尝试做什么,请查看以下内容。

aggregate( . ~ a, data = DF, FUN = sum )

两列 b 和 c 是聚合的,但从第一次尝试中我们知道您不能执行单独访问每一列的操作。因此,严格遵守聚合需要两遍和三行代码。

diffb <- aggregate( b ~ a, data = DF, FUN = diff )
Y <- aggregate( c ~ a, data = DF, FUN = sum )
Y$c <- diffb$b / Y$c

现在 Y 包含您想要的结果。

by函数比它更简单aggregate,它所做的只是data.frame使用索引拆分原始文件,然后应用该FUN函数。

l <- by( data = DF, INDICES = DF$a, FUN = function(x) diff(x$b)/sum(x$c), simplify = FALSE )
unlist(l)

data.frame如果你真的想要一个,你必须做一些事情才能将结果恢复到 a中。

data.frame(a = names(l), x = unlist(l))
于 2012-09-12T12:37:36.990 回答
2

使用data.table可能更快更容易。

library(data.table)
DT <- data.table(DF)
DT[, (-1*diff(b))/sum(c), by=a]
  a         V1
1: A  1.2000000
2: B -0.8750000
3: C -0.4117647
4: D  0.2727273
5: E  0.1428571

使用聚合,不太好。我没有更好的方法来使用aggregate:(但这是一个尝试。

B <- aggregate(DF$b, by=list(DF$a), diff)
C <- aggregate(DF$c, by=list(DF$a), sum)
data.frame(a=B[,1], Result=(-1*B[,2])/C[,2])
  a     Result
1 A  1.2000000
2 B -0.8750000
3 C -0.4117647
4 D  0.2727273
5 E  0.1428571
于 2012-09-12T12:46:49.970 回答
1

一个data.table解决方案 - 时间和内存的效率。

library(data.table)
DT <- as.data.table(DF)

DT[, list(calc = diff(b) / sum(c)), by = a]
于 2012-09-12T12:49:48.760 回答
0

您可以使用基本by()功能:

listOfRows <- 
by(data=DF,
   INDICES=DF$a,
   FUN=function(x){data.frame(a=x$a[1],res=(x$b[1] - x$b[2])/(x$c[1] + x$c[2]))})

newDF <- do.call(rbind,listOfRows)
于 2012-09-12T11:00:25.770 回答