hklovs
hklovs

Reputation: 642

check variables and group them according to group belonging

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

Answers (3)

Chuck P
Chuck P

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

ThomasIsCoding
ThomasIsCoding

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

Darren Tsai
Darren Tsai

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

Related Questions