eyei
eyei

Reputation: 402

How to fill a column based on a condition using sum() for matches in r

I have struggles filling a column based on a condition. Maybe my approach is not in the right direction. I don't know. My conditions are as follow:

So far I did the following but I see that this is not quite accurate since my new vector is not created from the rows but the entire column, and it still doesn't work.

set.seed(123)
df_letters <- data.frame(basket1 = sample(letters[1:3], 5,  replace = TRUE, prob = c(0.85,0.10,0.5)),
                        basket2 = sample(letters[1:3], 5,  replace = TRUE, prob = c(0.10,0.85,0.5)),
                        basket3 = sample(letters[1:3], 5,  replace = TRUE, prob=c(0.5,0.10,0.85)),
                        stringsAsFactors = FALSE)


df_letters %>% mutate(match = ifelse(sum(as.character(as.vector(df_letters))  == "c")==2, "C", 
                                    ifelse((sum(as.character(as.vector(df_letters))  == "b")==2) & (sum(as.character(as.vector(df_letters))  == "a")==1) ,"B", NA  )))

My desired output is:

> df_letters
  basket1 basket2 basket3 match
1       a       b       b     B
2       c       b       c     C
3       a       c       a  <NA>
4       c       b       c     C
5       b       b       c  <NA>

Many thanks in advance!

Upvotes: 0

Views: 159

Answers (2)

slava-kohut
slava-kohut

Reputation: 4233

This is how to achieve this in base R:

df_letters$match <- apply(df_letters, 1, function(x) {
  count <- as.list(table(x))
  ifelse(count$a == 1 && count$b == 2, "B", ifelse(count$c == 2, "C", NA_character_))
})

The idea is to convert the table object to list to access counts by element.

Output

      basket1 basket2 basket3 match
1       a       b       b     B
2       c       b       c     C
3       a       c       a  <NA>
4       c       b       c     C
5       b       b       c  <NA>

Upvotes: 1

tmfmnk
tmfmnk

Reputation: 39858

One dplyr option could be:

df_letters %>%
 mutate(match = case_when(rowSums(select(., starts_with("basket")) == "b") == 2 & rowSums(select(., starts_with("basket")) == "a") == 1 ~ "B",
                          rowSums(select(., starts_with("basket")) == "c") == 2 ~ "C",
                          TRUE ~ NA_character_))

  basket1 basket2 basket3 match
1       a       b       b     B
2       c       b       c     C
3       a       c       a  <NA>
4       c       b       c     C
5       b       b       c  <NA>

Upvotes: 1

Related Questions