Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to duplicate and replace certain values in duplicated records multiple times using R and dplyr?

I have records in a dataframe that I want to duplicate multiple times, and apply some changes to each iteration of duplicate rows.

Using the following dataframe:

name <- c("Kiwi","Orange","Apple")
val1 <- c(1,9,10)
val2 <- c(1,1,1)

df <- data.frame(name, val1, val2)

I can duplicate the row where name == "Apple" and replace the name in the duplicate row:

df.2 <- df %>% 
            filter(name == "Apple") %>% 
            mutate(name = "Strawberry") %>%
            bind_rows(., df)

However running this operation more than once does not work as expected:

df.2 <- df %>% 
            filter(name == "Apple") %>% 
            mutate(name = "Strawberry") %>%
            bind_rows(., df) %>%
            filter(name == "Apple") %>% 
            mutate(name = "Dragonfruit") %>%
            bind_rows(., df)

Expected result:

val1 <- c(10,10,1,9,10)
val2 <- c(1,1,1,1,1)
name <- c("Dragonfruit","Strawberry","Kiwi","Orange","Apple")

expected.result <- data.frame(name, val1, val2)
            
like image 592
plast1cd0nk3y Avatar asked Dec 12 '25 16:12

plast1cd0nk3y


1 Answers

df %>% 
  mutate(name = replace(name, which(name == 'Apple'),
                        list(c('Apple', 'Strawberry', 'Dragonfruit')))) %>% 
  unnest_longer(name)
#> # A tibble: 5 × 3
#>   name         val1  val2
#>   <chr>       <dbl> <dbl>
#> 1 Kiwi            1     1
#> 2 Orange          9     1
#> 3 Apple          10     1
#> 4 Strawberry     10     1
#> 5 Dragonfruit    10     1

or

df %>% 
  mutate(name = if_else(name != 'Apple', name,
                        paste(name, 'Strawberry', 'Dragonfruit'))) %>% 
  separate_rows(name, sep = ' ')
#> # A tibble: 5 × 3
#>   name         val1  val2
#>   <chr>       <dbl> <dbl>
#> 1 Kiwi            1     1
#> 2 Orange          9     1
#> 3 Apple          10     1
#> 4 Strawberry     10     1
#> 5 Dragonfruit    10     1

or

df %>% 
  filter(name == 'Apple') %>% 
  reframe(name = c('Strawberry', 'Dragonfruit'), across(-name)) %>% 
  bind_rows(df, .)
#>          name val1 val2
#> 1        Kiwi    1    1
#> 2      Orange    9    1
#> 3       Apple   10    1
#> 4  Strawberry   10    1
#> 5 Dragonfruit   10    1

or

df %>% 
  filter(name == 'Apple') %>% 
  select(-name) %>% 
  expand_grid(name = c('Strawberry', 'Dragonfruit')) %>% 
  bind_rows(df, .)
#>          name val1 val2
#> 1        Kiwi    1    1
#> 2      Orange    9    1
#> 3       Apple   10    1
#> 4  Strawberry   10    1
#> 5 Dragonfruit   10    1

or

df %>% 
  uncount(if_else(name == 'Apple', 3, 1)) %>% 
  mutate(name = replace(name, which(name == 'Apple')[-1],
                        c('Strawberry', 'Dragonfruit')))
#>          name val1 val2
#> 1        Kiwi    1    1
#> 2      Orange    9    1
#> 3       Apple   10    1
#> 4  Strawberry   10    1
#> 5 Dragonfruit   10    1
like image 141
IceCreamToucan Avatar answered Dec 14 '25 07:12

IceCreamToucan