最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

r - After group_by, data manipulation based off of condition in the same group? - Stack Overflow

programmeradmin3浏览0评论

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
  • Please provide enough code so others can better understand or reproduce the problem. – Community Bot Commented Feb 16 at 18:05
  • 3 I don't see how this is a 'typo' or 'not reproducible' in the specific way that a question should be closed for. Yes, if it was a nice 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
  • It's almost certainly a duplicate. – IRTFM Commented Feb 18 at 19:28
Add a comment  | 

2 Answers 2

Reset to default 2

We 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"
发布评论

评论列表(0)

  1. 暂无评论