R中每组的条件累积平均值

Conditional cumulative mean for each group in R

我有一个如下所示的数据集:

id   a   b
1    AA  2
1    AB  5
1    AA  1
2    AB  2
2    AB  4
3    AB  4
3    AB  3
3    AA  1

我需要计算每个组内每条记录的累积平均值并排除 a == 'AA' 的情况,因此示例输出应为:

id   a   b  mean
1    AA  2   -
1    AB  5   5
1    AA  1   5
2    AB  2   2
2    AB  4   (4+2)/2
3    AB  4   4
3    AB  3   (4+3)/2
3    AA  1   (4+3)/2
3    AA  4   (4+3)/2

我尝试使用 dplyr 和 cummean 来实现它,但出现错误。

df <- df %>%
       group_by(id) %>%
       mutate(mean = cummean(b[a != 'AA']))

Error: incompatible size (123), expecting 147 (the group size) or 1

你能推荐一个更好的方法来在 R 中实现同样的效果吗?

可能有更简单的方法。在这里,我们按 'id' 分组。通过首先将 'b' 中对应于 'a' 中的 'AA' 的元素转换为 NA (b*NA^(a=='AA')) 来创建一个新列 'Mean'。 NA^(a=='AA') 为 'a' 中的 'AA' 提供 NA 的输出,为所有其他值提供 1。因此,当我们乘以 'b' 时,它将 1 替换为 'b' 中的值,而 NA 保持不变。我们使用 na.aggregate 将 'NA' 替换为每组中非 NA 元素的 mean,然后用 cummean 换行以获得累积平均值。如果 'a' 每组中的第一个值是 'AA',我们可以通过乘以 NA^(row_number()==1 & a=='AA').

得到 NA
library(zoo)
library(dplyr)
df %>% 
   group_by(id) %>% 
   mutate(Mean= cummean(na.aggregate(b*NA^(a=='AA')))*
                 NA^(row_number()==1 & a=='AA'))
# Source: local data frame [9 x 4]
#Groups: id [3]

#      id     a     b  Mean
#   (int) (chr) (int) (dbl)
#1     1    AA     2    NA
#2     1    AB     5   5.0
#3     1    AA     1   5.0
#4     2    AB     2   2.0
#5     2    AB     4   3.0
#6     3    AB     4   4.0
#7     3    AB     3   3.5
#8     3    AA     1   3.5
#9     3    AA     4   3.5

数据

df <- structure(list(id = c(1L, 1L, 1L, 2L, 2L, 3L, 3L, 3L, 3L), 
a = c("AA", 
"AB", "AA", "AB", "AB", "AB", "AB", "AA", "AA"), b = c(2L, 5L, 
1L, 2L, 4L, 4L, 3L, 1L, 4L)), .Names = c("id", "a", "b"),
class = "data.frame", row.names = c(NA, -9L))

这里的技巧是通过将调整后的 cumsum 除以调整后的计数来重构 cummean。作为单线:

df %>% group_by(id) %>% mutate(cumsum(b * (a != 'AA')) / cumsum(a != 'AA'))

我们可以通过将 a != 'AA' 作为列

df %>%
    group_by(id) %>%
    mutate(relevance = 0+(a!='AA'), 
           mean = cumsum(relevance * b) / cumsum(relevance))