megv
megv

Reputation: 1461

remove elements from a data.frame with lists of lists

I have a data.frame of length 3 - sku_data: A sample of the data is:

sku_data <- data.frame(
  sku = c(1200337,1200518,1200586,1200590),
  units_current = I(list(c(1),1:3,1:4,2:4)),
  units_end = I(list(1:3,1,2:4,1:3))
)

#      sku units_current units_end
#1 1200337             1   1, 2, 3
#2 1200518       1, 2, 3         1
#3 1200586    1, 2, 3, 4   2, 3, 4
#4 1200590       2, 3, 4   1, 2, 3

I want to remove those elements where the length of units_current or units_end is <=1. They are both lists of lists.

Thanks

Upvotes: 1

Views: 57

Answers (2)

akrun
akrun

Reputation: 886978

Another option is:

sku_data[!rowSums(`dim<-`(rapply(sku_data[,-1], length) <=1,
                                         dim(sku_data)-c(0,1))),]
#      sku units_current units_end
#3 1200586    1, 2, 3, 4   2, 3, 4
#4 1200590       2, 3, 4   1, 2, 3

Upvotes: 0

Rich Scriven
Rich Scriven

Reputation: 99331

How about:

f <- function(x) which(sapply(x, length) <= 1L)

sku_data[-unlist(lapply(sku_data[-1], f)), ]
#       sku units_current units_end
# 3 1200586    1, 2, 3, 4   2, 3, 4
# 4 1200590       2, 3, 4   1, 2, 3

And testing on more than one/uneven length matches

(sku2 <- rbind(sku_data, sku_data, sku_data[1,]))
#       sku units_current units_end
# 1 1200337             1   1, 2, 3
# 2 1200518       1, 2, 3         1
# 3 1200586    1, 2, 3, 4   2, 3, 4
# 4 1200590       2, 3, 4   1, 2, 3
# 5 1200337             1   1, 2, 3
# 6 1200518       1, 2, 3         1
# 7 1200586    1, 2, 3, 4   2, 3, 4
# 8 1200590       2, 3, 4   1, 2, 3
# 9 1200337             1   1, 2, 3
sku2[-unlist(lapply(sku2[-1], f)), ]
#       sku units_current units_end
# 3 1200586    1, 2, 3, 4   2, 3, 4
# 4 1200590       2, 3, 4   1, 2, 3
# 7 1200586    1, 2, 3, 4   2, 3, 4
# 8 1200590       2, 3, 4   1, 2, 3

Upvotes: 2

Related Questions