1

My code is dirty. if condition smaller than two, names = unpopular.

df <- data.frame(vote=c("A","A","A","B","B","B","B","B","B","C","D"),
           val=c(rep(1,11))
           )

df %>% group_by(vote) %>% summarise(val=sum(val))
out

  vote    val
  <fct> <dbl>
1 A         3
2 B         6
3 C         1
4 D         1

but I need

  vote    val
  <fct> <dbl>
1 A         3
2 B         6
3 unpopular 2

my idea is

df2 <- df %>% group_by(vote) %>% summarise(val=sum(val))
df2$vote[df2$val < 2] <- "unpop"
df2 %>% group_by....

it's not cool.

do you know any cool & helpful function ?

2 Answers 2

2

We can do a double grouping

library(dplyr)
df %>% 
    group_by(vote) %>% 
    summarise(val=sum(val)) %>%
    group_by(vote = replace(vote, val <2, 'unpop')) %>% 
    summarise(val = sum(val))

-output

# A tibble: 3 x 2
# vote    val
#  <chr> <dbl>
#1 A         3
#2 B         6
#3 unpop     2

Or another option with rowsum

df %>% 
   group_by(vote = replace(vote, vote %in% 
     names(which((rowsum(val, vote) < 2)[,1])), 'unpopular')) %>% 
   summarise(val = sum(val))

Or using fct_lump_n from forcats

library(forcats)
df %>% 
  group_by(vote = fct_lump_n(vote, 2, other_level = "unpop")) %>%
  summarise(val = sum(val))
# A tibble: 3 x 2
#  vote    val
#  <fct> <dbl>
#1 A         3
#2 B         6
#3 unpop     2

Or using table

df %>%
   group_by(vote = replace(vote, 
      vote %in% names(which(table(vote) < 2)), 'unpop'))  %>%
   summarise(val = sum(val))
Sign up to request clarification or add additional context in comments.

Comments

1

If you want to vote based on sum of val in base R you can do this as :

aggregate(val~vote, transform(aggregate(val~vote, df, sum), 
          vote = replace(vote, val < 2, 'unpop')), sum)

#   vote val
#1     A   3
#2     B   6
#3 unpop   2

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.