我有一个包含两列的数据框:
A B
1 5
2 4
1 3
2 2
3 5
我需要的是计算A中某个类的B中所有值的均值: 例如,计算来自B的所有值的计算均值(仅对应于A中的0和2之间)和2-4的相同值 所以我的班级来自A 0-2 2-4 4-6
任何想法?
答案 0 :(得分:1)
这取决于您的间隔是否包含(是0-2间隔和2-4间隔中包含的第二行,或者只是其中之一)。
如果间隔未关闭(间隔至少是半开)且相邻,则@akrun在评论中使用cut
函数创建新的分组因子{{1}然后使用tapply使用cut(df$A, breaks=2*(0:3))
基于此应用均值。此方法不会处理需要关闭间隔的情况,或者可能会在多个间隔内处理点。它也不会给你一个没有点数下降的时间间隔的值(可能需要也可能不需要)。间隔也必须相邻。
以下方法允许任意间隔,默认情况下,识别没有点落下的间隔。允许的点数不止一个。
tapply(df$B,cut(df$A, breaks=2*0:3,FUN=mean)
此处,剪切矩阵将包含实际的间隔边界:
df<-data.frame(A=c(1,2,1,2,3),B=c(5,4,3,2,5))
cuts<-matrix(c(0,2,2,4,4,6),ncol=2,byrow=TRUE)
现在我们编写选择区间 †
中的元素的函数 [,1] [,2]
[1,] 0 2
[2,] 2 4
[3,] 4 6
此处 cls 期望接收值的向量和给出间隔的上边界和下边界的向量。它返回一个布尔向量,指示值是否在区间内。例如,cls<-function(vals,cat) {(vals>=cat[1]&vals<=cat[2])}
生成
cls(df$A,c(0,2))
告诉我们除A的最后一个值之外的所有值都在0到2之间。
最后,我们可以找到每个区间的B值的平均值,如此, ‡
[1] TRUE TRUE TRUE TRUE FALSE
这将处理剪切矩阵中的每一行(第1个选项意味着按行表示),并计算与该行指定的间隔中的A值对应的B值的平均值( apply(cuts,1,function(x){mean(df$B[cls(df$A,x)])})
使用我们的 cls 函数在x指定的区间内查找A值,然后选择与此对应的B值 - 返回值为 TRUE的值)。
结果是
df$B[cls(df$A,x)]
这告诉我们对应于0到2的A值的B值的平均值是3.5,对应于2到4的A值的B值的平均值是3和2/3,并且没有B对应于4到6的A值的值(因为没有这样的A值)。
† 如果需要半开,则很容易修改 cls 。如果我们希望排除正确的边界,我们可以使用
[1] 3.500000 3.666667 NaN
如果我们希望排除下边界,我们可以使用
cls<-function(vals,cat) {(vals>=cat[1]&vals<cat[2])}
或使用严格开放的间隔,我们可以做
cls<-function(vals,cat) {(vals>cat[1]&vals<=cat[2])}
但是,在这些情况下,使用内置cls<-function(vals,cat) {(vals>cat[1]&vals<cat[2])}
功能可能是最好的。
‡ 如果您不想创建 cls 功能,整个选择可以像
一样内联cut
或者,也不需要 cut 变量,
apply(cuts,1,function(x){mean(df$B[df$A>=x[1]&df$A<=x[2]])})
答案 1 :(得分:-1)
tapply功能是您所需要的。
phinx migrate -e development
应该做的伎俩。对于更大的数据,有更有效的方法可以做到这一点。另请查看group_by并在dplyr中进行汇总。