Question Details

No question body available.

Tags

r aggregate

Answers (4)

July 15, 2026 Score: 2 Rep: 274,661 Quality: Medium Completeness: 60%

1) Encode B and C into the real and imaginary parts of a complex vector and then you can pass both at the same time. At the end pick out the real part.

with(x, Re(ave(B + C*1i, A, FUN = \(z) mean(Re(z)[Im(z) < 3]))))
[1] 1.5 1.5 3.5 3.5 3.5

2) Another possibility is to work with the row indexes:

with(x, ave(seq_along(C) + 0, A, FUN = \(i) with(x[i, ], mean(B[C < 3]))))
[1] 1.5 1.5 3.5 3.5 3.5

3) If we can use other functions then keeping with base R we can use by like this:

do.call("rbind", by(x, x$A, transform, D = mean(B[C < 3])))$D
[1] 1.5 1.5 3.5 3.5 3.5

4) Someone else had the idea of using NA but they deleted their answer so here is an approach to that.

with(x, ave(ifelse(C < 3, B, NA), A, FUN = \(b) mean(b, na.rm = TRUE)))
[1] 1.5 1.5 3.5 3.5 3.5

5) IF we know that B is strictly positive as is the case in the question then we can encode the condition into the sign of B.

with(x, ave(ifelse(C < 3, B, -B), A, FUN = \(b) mean(b[b > 0])))
[1] 1.5 1.5 3.5 3.5 3.5
July 15, 2026 Score: 1 Rep: 7,518 Quality: Low Completeness: 30%

a {data.table} solution:

library(data.table)

as.data.table(x)[, B := mean(B[C < 3]), by = A][, B]

output:

[1] 1.5 1.5 3.5 3.5 3.5
July 15, 2026 Score: 1 Rep: 209,886 Quality: Low Completeness: 30%

With dplyr you do a mutate with a .by condition

x |> mutate(D=mean(B[C pull(D)

[1] 1.5 1.5 3.5 3.5 3.5

July 15, 2026 Score: 1 Rep: 79,146 Quality: Low Completeness: 70%

Yet another ave way.
Subset the data.frame, selecting only the columns involved in computing the mean. Then ave will compute the means for each of B and C, but the result is a data.frame so extract column B.

x  [1] 1.5 1.5 3.5 3.5 3.5

Created on 2026-07-15 with reprex v2.1.1