Rtist
Rtist

Reputation: 4205

How to duplicate a row based on the levels of a factor, in R

I have the following data frame

MyData = data.frame(
  id = 1:2, 
  choice = factor(c('red', 'blue')),
  grade = c(60, 70))

  id choice grade
1  1    red    60
2  2   blue    70

I want to duplicate each row according to the level of 'choice'. Thus, row should be duplicated one time for each level of the variable 'choice'. So I need one row for the level 'blue' and one for 'red'. As follows:

  id choice grade
1  1   blue    60
2  1    red    60
3  2   blue    70
4  2    red    70

I looked at several questions on stackoverflow but typically, people want to remove duplicates based on a factor, not creating them. Any idea how doing that? A solution based on tidyr/dplyr would be appreciated.

Upvotes: 0

Views: 555

Answers (3)

s_baldur
s_baldur

Reputation: 33488

Here is some playing around with expand.grid() from base R:

library(dplyr)
with(MyData, expand.grid(id = id, choice = choice)) %>% 
  left_join(
    y = MyData %>% select(id, grade), 
    by = "id"
  )

  id choice grade
1  1    red    60
2  2    red    70
3  1   blue    60
4  2   blue    70

Upvotes: 1

A. Suliman
A. Suliman

Reputation: 13125

We can use levels(choice) to get all levels then do separate_rows

library(dplyr)
library(tidyr)
mutate(MyData, choice=toString(levels(choice))) %>% separate_rows(choice)

id choice grade
1  1   blue    60
2  1    red    60
3  2   blue    70
4  2    red    70

Upvotes: 1

talat
talat

Reputation: 70266

Here's a dplyr & tidyr approach:

library(dplyr); library(tidyr)
MyData %>% 
  group_by(id) %>% 
  complete(choice, grade)

#     id choice grade
#  <int> <fct>  <dbl>
#1     1 blue      60
#2     1 red       60
#3     2 blue      70
#4     2 red       70

Upvotes: 1

Related Questions