My goal is to do a cross group redaction. So I would need create a column that would look to see if the group ever has been redacted, and if so then also redact the other value in the same group
For example, I would want to turn this table:
id | value | redact |
---|---|---|
A | 3 | N < 4 |
A | 5 | |
B | 6 | |
B | 6 | |
C | 5 | |
C | 3 | N < 4 |
D | 5 | |
D | 6 | |
E | 2 | N < 4 |
E | 8 |
My goal is to do a cross group redaction. So I would need create a column that would look to see if the group ever has been redacted, and if so then also redact the other value in the same group
For example, I would want to turn this table:
id | value | redact |
---|---|---|
A | 3 | N < 4 |
A | 5 | |
B | 6 | |
B | 6 | |
C | 5 | |
C | 3 | N < 4 |
D | 5 | |
D | 6 | |
E | 2 | N < 4 |
E | 8 |
Into this one:
id | value | redact |
---|---|---|
A | 3 | N < 4 |
A | 5 | crossGroup |
B | 6 | |
B | 6 | |
C | 5 | crossGroup |
C | 3 | N < 4 |
D | 5 | |
D | 6 | |
E | 2 | N < 4 |
E | 8 | crossGroup |
While I am able to successfully do a conditional mutation to check the value is less than 4, I am stuck on how to mutate the other row in the same group
Share Improve this question asked Feb 16 at 17:08 midknightowlmidknightowl 191 bronze badge 3 |2 Answers
Reset to default 2We could try ave
.
X$redact =
ave(X$redact, X$id, FUN = \(x) { i = x!=''; if(any(i)) x[!i]='crossGroup'; x })
> X
id value redact
1 A 3 N < 4
2 A 5 crossGroup
3 B 6
4 B 6
5 C 5 crossGroup
6 C 3 N < 4
7 D 5
8 D 6
9 E 2 N < 4
10 E 8 crossGroup
Data
> dput(X)
structure(list(id = c("A", "A", "B", "B", "C", "C", "D", "D",
"E", "E"), value = c(3L, 5L, 6L, 6L, 5L, 3L, 5L, 6L, 2L, 8L),
redact = c("N<4", "", "", "", "", "N<4", "", "", "N<4", ""
)), class = "data.frame", row.names = c(NA, -10L))
Using dplyr
:
X |>
group_by(id) |>
mutate(
redact = ifelse(redact != 'N<4' & any(redact == 'N<4'), 'crossGroup', redact)
)
Or perhaps it's better to do (your example is rather ambiguous):
X |>
group_by(id) |>
mutate(
redact = ifelse(redact == '' & any(redact != ''), 'crossGroup', redact)
)
# A tibble: 10 × 3 # Groups: id [5] id value redact <chr> <int> <chr> 1 A 3 "N<4" 2 A 5 "crossGroup" 3 B 6 "" 4 B 6 "" 5 C 5 "crossGroup" 6 C 3 "N<4" 7 D 5 "" 8 D 6 "" 9 E 2 "N<4" 10 E 8 "crossGroup"
dput
or reproducible code, that would be nicer, but it's a reasonable question. Anyway, this doesn't require any group-by logic at all -dat$redact[dat$id %in% dat$id[dat$redact == "N<4"] & dat$redact == ""] <- "crossGroup"
– thelatemail Commented Feb 16 at 22:44