基于行满足一定条件的R变异结构

gblwokeq  于 12个月前  发布在  其他
关注(0)|答案(2)|浏览(82)

我希望在一个基于行值在现有行的一定范围内的嵌套框架中改变一个新行。
类似于以下内容:

df <- data.frame(
  "a" = c(1, 2, 3, 4, 5, 8, 9, 15, 22, 60),
  "b" = c(2, 3, 4, 5, 6, 7, 8, 9,  10, 11)
)

df <- df %>%
  mutate(c = mean(if(~a <= a, ~b)))

字符串
其中“~a”是指“a”值的整个列,并且“a”是指正在突变的特定行。
编辑:所以c的预期输出是:(2,[a小于第一个a的b值的平均值] 2.5 [a小于第二个a的b值的平均值],以此类推)。在实践中,我有多个“if”条件,所以它不仅仅是一个累积和/平均值。
我在网上找到了一些解决方案,其中if语句是特定的(例如,mutate if ~a < 5),但不是基于a的当前行值。

b4lqfgs4

b4lqfgs41#

由于a已经排序(至少你的例子是这样呈现的),你等价地计算b的滚动平均值,样本数不同(取决于a的位置)
你可以像下面这样尝试cummean

df %>%
  mutate(c = cummean(b))

字符串
它应该给予

a  b   c
1   1  2 2.0
2   2  3 2.5
3   3  4 3.0
4   4  5 3.5
5   5  6 4.0
6   8  7 4.5
7   9  8 5.0
8  15  9 5.5
9  22 10 6.0
10 60 11 6.5

一般情况下(未排序a

例如,如果a未排序,则可以使用以下代码

df %>%
  mutate(c = colMeans(b * NA^!outer(a, a, `<=`), TRUE))


或更有效(感谢@Onyambu的评论)

df %>%
  mutate(c=cummean(b[o<-order(a)])[match(row_number(), o)])


它给出了相同的输出

a  b   c
1   1  2 2.0
2   2  3 2.5
3   3  4 3.0
4   4  5 3.5
5   5  6 4.0
6   8  7 4.5
7   9  8 5.0
8  15  9 5.5
9  22 10 6.0
10 60 11 6.5


对于未排序的示例,

set.seed(0)
df <- data.frame(
  "a" = sample(c(1, 2, 3, 4, 5, 8, 9, 15, 22, 60)),
  "b" = c(2, 3, 4, 5, 6, 7, 8, 9, 10, 11)
)

我们可以实现

a  b        c
1  22  2 6.222222
2   4  3 5.500000
3   9  4 6.142857
4   1  5 5.000000
5   2  6 5.500000
6   5  7 5.800000
7   3  8 6.333333
8  60  9 6.500000
9   8 10 6.500000
10 15 11 6.750000
apeeds0o

apeeds0o2#

您需要将a列降到最低,可以在mutate中使用sapply执行此操作

df %>%
  mutate(c = sapply(a, \(x) mean(b[a <= x])))
#>     a  b   c
#> 1   1  2 2.0
#> 2   2  3 2.5
#> 3   3  4 3.0
#> 4   4  5 3.5
#> 5   5  6 4.0
#> 6   8  7 4.5
#> 7   9  8 5.0
#> 8  15  9 5.5
#> 9  22 10 6.0
#> 10 60 11 6.5

字符串

相关问题