subsetting a nested list based on a conidtion in R

Viewed 38

my nested list looks like this:

  myList <- list(structure(list(id = 1:3, value = c(22, 33, 44), 
                                code = c("943", "943", "3a0"), 
                                product = c("Product 1", "Product 1", "Product 1")),
                           row.names = c(NA,-3L), 
                           class = c("data.table", "data.frame")), 
                 structure(list(id = 1:3, value = c(22, 33, 44), 
                                code = c("943", "94f", "3a0"), 
                                product = c("Product 2", "Product 2", "Product 2")),
                           row.names = c(NA,-3L), 
                           class = c("data.table", "data.frame")),
                 structure(list(id = 1:3, value = c(22, 33, 44), 
                                code = c("977", "943", "3a0"), 
                                product = c("Product 3", "Product 3", "Product 3")),
                           row.names = c(NA,-3L), 
                           class = c("data.table", "data.frame")))

i want to remove all list objects that have more than one list element with the same code. For example the first object [[1]] has two entries that have the code 943. I want to remove the entire object and keep only those that do not have any duplicates.

The expected outcome would therefore be:   myList <- list(
    structure(list(id = 1:3, value = c(22, 33, 44), 
                   code = c("943", "94f", "3a0"), 
                   product = c("Product 2", "Product 2", "Product 2")),
              row.names = c(NA,-3L), 
              class = c("data.table", "data.frame")),
    structure(list(id = 1:3, value = c(22, 33, 44), 
                   code = c("977", "943", "3a0"), 
                   product = c("Product 3", "Product 3", "Product 3")),
              row.names = c(NA,-3L), 
              class = c("data.table", "data.frame")))

I was thinking of using and lapply, but i couldnt get it to qwork

any(duplicated(myList[[1]]$code))

any ides or suggestion?

this seems like a relatively simple problem, but i cant figure it out

2 Answers

Your code any(duplicated(myList[[1]]$code)) can be used in Filter

Filter(function(x) !any(duplicated(x$code)), myList)

#[[1]]
#   id value code   product
#1:  1    22  943 Product 2
#2:  2    33  94f Product 2
#3:  3    44  3a0 Product 2

#[[2]]
#   id value code   product
#1:  1    22  977 Product 3
#2:  2    33  943 Product 3
#3:  3    44  3a0 Product 3

Or with purrr :

purrr::keep(myList, ~!any(duplicated(.x$code)))
purrr::discard(myList, ~any(duplicated(.x$code)))

Does this work:

myList[sapply(lapply(myList, function(x) +duplicated(x$code)), function(x) sum(x) == 0)]
[[1]]
   id value code   product
1:  1    22  943 Product 2
2:  2    33  94f Product 2
3:  3    44  3a0 Product 2

[[2]]
   id value code   product
1:  1    22  977 Product 3
2:  2    33  943 Product 3
3:  3    44  3a0 Product 3
Related