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))
我有一个如下所示的数据集:
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))