Reputation: 642
I want to check variables and group them according to which group they belong. If they belong to both groups, it gets marked with "X"
.
grp1 <- c("A","B","C","D","E")
grp2 <- c("F","G","H","I","J","K")
DF <- data.frame(id = c(1,1,2,3,3), dis = c("A","B","H","B","K"))
DF
id dis
1 1 A
2 1 B
3 2 H
4 3 B
5 3 K
And the result should look like this:
id dis grp
1 1 A 1
2 1 B 1
3 2 H 2
4 3 B X
5 3 K X
Any good ideas?
Upvotes: 2
Views: 119
Reputation: 3923
A dplyr
solution
library(dplyr)
DF %>%
mutate(grps = case_when(
dis %in% grp1 ~ 1,
dis %in% grp2 ~ 2)
) %>%
group_by(id) %>%
mutate(temp = mean(grps)) %>%
mutate(grp = case_when(
temp == 1 ~ "1",
temp == 2 ~ "2",
temp == 1.5 ~ "X")
) %>%
select(-grps,-temp)
#> # A tibble: 5 x 3
#> # Groups: id [3]
#> id dis grp
#> <dbl> <chr> <chr>
#> 1 1 A 1
#> 2 1 B 1
#> 3 2 H 2
#> 4 3 B X
#> 5 3 K X
Upvotes: 1
Reputation: 102920
Another base R option via ave
within(DF, grp <- ave(dis, id, FUN = function(x) {
if (all(x %in% grp1)) {
"1"
} else if (all(x %in% grp2)) {
"2"
} else {
"x"
}
}))
which gives
id dis grp
1 1 A 1
2 1 B 1
3 2 H 2
4 3 B x
5 3 K x
Upvotes: 3
Reputation: 35737
A base
solution with merge()
and ave()
DF2 <- setNames(stack(list(`1` = grp1, `2` = grp2)), c("dis", "grp"))
DF3 <- merge(DF, DF2, all.x = T)
DF3 <- within(DF3[order(DF3$id), ], grp <- ave(as.character(grp), id,
FUN = function(x) if(length(unique(x)) == 1) x[1] else "X"))
DF3
# dis id grp
# 1 A 1 1
# 2 B 1 1
# 4 H 2 2
# 3 B 3 X
# 5 K 3 X
Upvotes: 1