Using dplyr is there a way to keep rows but add blank to selected repeating values

Viewed 35

I have a dataset that looks like this

Col1|Col2| Col3|Col4
 101 Dog   Sep  Grooming 
 101 Dog   Sep  Birthday
 303 Cat   Oct  Birthday
 404 Dog   Sep  Grooming

I would want to create a dplyr script that recognizes row 1 and 2 as duplicates by the first three columns and then turns the second row blank with the exception of the 4th column. I don't want to delete the row.

    Col1|Col2| Col3|Col4
 101 Dog   Sep  Grooming 
                Birthday
 303 Cat   Oct  Birthday
 404 Dog   Sep  Grooming
2 Answers

Not the cleanest answer

library(tidyverse)

example_data <- read_table(r"(
                           Col1 Col2 Col3 Col4
                           101 Dog Sep Grooming 
                           101 Dog Sep Birthday
                           303 Cat Oct Birthday
                           404 Dog Sep Grooming)")
#> Warning: 1 parsing failure.
#> row col  expected    actual         file
#>   1  -- 4 columns 5 columns literal data


example_data %>%
  group_by(sequence = str_c(Col1,Col2,Col3)) %>% 
  mutate(across(c(Col1,Col2,Col3),.fns = ~ replace(.x,duplicated(.x),""))) %>%
  ungroup() %>% 
  select(-sequence)
#> # A tibble: 4 x 4
#>   Col1  Col2  Col3  Col4    
#>   <chr> <chr> <chr> <chr>   
#> 1 "101" "Dog" "Sep" Grooming
#> 2 ""    ""    ""    Birthday
#> 3 "303" "Cat" "Oct" Birthday
#> 4 "404" "Dog" "Sep" Grooming

Created on 2021-08-17 by the reprex package (v2.0.1)

We can use base R

dat1[duplicated(dat1[1:3]), 1:3] <- ""

-output

> dat1
  Col1 Col2 Col3     Col4
1  101  Dog  Sep Grooming
2                Birthday
3  303  Cat  Oct Birthday
4  404  Dog  Sep Grooming

data

dat1 <- structure(list(Col1 = c(101L, 101L, 303L, 404L), Col2 = c("Dog", 
"Dog", "Cat", "Dog"), Col3 = c("Sep", "Sep", "Oct", "Sep"), Col4 = c("Grooming", 
"Birthday", "Birthday", "Grooming")), class = "data.frame", row.names = c(NA, 
-4L))
Related