List filtering

List filtering is to select list members that meet given criteria. In rlist package, more than ten functions are related with list filtering. Basically, they all perform a mapping but aggregate the results in different ways.

devs <- 
  list(
    p1=list(name="Ken",age=24,
      interest=c("reading","music","movies"),
      lang=list(r=2,csharp=4,python=3)),
    p2=list(name="James",age=25,
      interest=c("sports","music"),
      lang=list(r=3,java=2,cpp=5)),
    p3=list(name="Penny",age=24,
      interest=c("movies","reading"),
      lang=list(r=1,cpp=4,python=2)))

list.filter

list.filter filters a list by an expression that returns a logical value. Only the list members for which the value of that expression turns out to be TRUE will be part of the results.

str(list.filter(devs, age >= 25))
# List of 1
#  $ p2:List of 4
#   ..$ name    : chr "James"
#   ..$ age     : num 25
#   ..$ interest: chr [1:2] "sports" "music"
#   ..$ lang    :List of 3
#   .. ..$ r   : num 3
#   .. ..$ java: num 2
#   .. ..$ cpp : num 5
str(list.filter(devs, "sports" %in% interest))
# List of 1
#  $ p2:List of 4
#   ..$ name    : chr "James"
#   ..$ age     : num 25
#   ..$ interest: chr [1:2] "sports" "music"
#   ..$ lang    :List of 3
#   .. ..$ r   : num 3
#   .. ..$ java: num 2
#   .. ..$ cpp : num 5
str(list.filter(devs, mean(as.numeric(lang)) >= 3))
# List of 2
#  $ p1:List of 4
#   ..$ name    : chr "Ken"
#   ..$ age     : num 24
#   ..$ interest: chr [1:3] "reading" "music" "movies"
#   ..$ lang    :List of 3
#   .. ..$ r     : num 2
#   .. ..$ csharp: num 4
#   .. ..$ python: num 3
#  $ p2:List of 4
#   ..$ name    : chr "James"
#   ..$ age     : num 25
#   ..$ interest: chr [1:2] "sports" "music"
#   ..$ lang    :List of 3
#   .. ..$ r   : num 3
#   .. ..$ java: num 2
#   .. ..$ cpp : num 5

Meta-symbols defined in lambda expression can also be used. The following code will pick up the list member whose index is even.

str(list.filter(devs, .i %% 2==0))
# List of 1
#  $ p2:List of 4
#   ..$ name    : chr "James"
#   ..$ age     : num 25
#   ..$ interest: chr [1:2] "sports" "music"
#   ..$ lang    :List of 3
#   .. ..$ r   : num 3
#   .. ..$ java: num 2
#   .. ..$ cpp : num 5

list.find

In some cases, we don't need to find all the results given the criteria. Rather, we only need to find a few, sometimes only one. list.find will avoid searching across all list member but stops at a specific number of items found.

list.find(devs, age >= 25, 1)
# $p2
# $p2$name
# [1] "James"
# 
# $p2$age
# [1] 25
# 
# $p2$interest
# [1] "sports" "music" 
# 
# $p2$lang
# $p2$lang$r
# [1] 3
# 
# $p2$lang$java
# [1] 2
# 
# $p2$lang$cpp
# [1] 5

list.findi

list.findi only returns the index of the members found.

list.findi(devs, age >= 23, 2)
# [1] 1 2

list.takeWhile

list.takeWhile keeps taking members while a condition holds true.

list.takeWhile(devs, lang$r >= 2)
# $p1
# $p1$name
# [1] "Ken"
# 
# $p1$age
# [1] 24
# 
# $p1$interest
# [1] "reading" "music"   "movies" 
# 
# $p1$lang
# $p1$lang$r
# [1] 2
# 
# $p1$lang$csharp
# [1] 4
# 
# $p1$lang$python
# [1] 3
# 
# 
# 
# $p2
# $p2$name
# [1] "James"
# 
# $p2$age
# [1] 25
# 
# $p2$interest
# [1] "sports" "music" 
# 
# $p2$lang
# $p2$lang$r
# [1] 3
# 
# $p2$lang$java
# [1] 2
# 
# $p2$lang$cpp
# [1] 5

list.skipWhile

list.skipWhile keeps skipping members while a condition holds true.

list.skipWhile(devs, lang$r <= 2)
# $p2
# $p2$name
# [1] "James"
# 
# $p2$age
# [1] 25
# 
# $p2$interest
# [1] "sports" "music" 
# 
# $p2$lang
# $p2$lang$r
# [1] 3
# 
# $p2$lang$java
# [1] 2
# 
# $p2$lang$cpp
# [1] 5
# 
# 
# 
# $p3
# $p3$name
# [1] "Penny"
# 
# $p3$age
# [1] 24
# 
# $p3$interest
# [1] "movies"  "reading"
# 
# $p3$lang
# $p3$lang$r
# [1] 1
# 
# $p3$lang$cpp
# [1] 4
# 
# $p3$lang$python
# [1] 2

list.if

list.if returns a logical vector that indicates whether a condition holds for each member of a list.

list.if(devs, "music" %in% interest)
#    p1    p2    p3 
#  TRUE  TRUE FALSE
list.if(devs, "java" %in% names(lang))
#    p1    p2    p3 
# FALSE  TRUE FALSE

list.which

list.if returns a integer vector of the indices of the members of a list that meet a given condition.

list.which(devs, "music" %in% interest)
# [1] 1 2
list.which(devs, "java" %in% names(lang))
# [1] 2

list.all

list.all returns TRUE if all the members of a list satisfy a given condition, or FALSE otherwise.

list.all(devs, mean(as.numeric(lang)) >= 3)
# [1] FALSE
list.all(devs, "r" %in% names(lang))
# [1] TRUE

list.any

list.any returns TRUE if at least one of the members of a list satisfies a given condition, or FALSE otherwise.

list.any(devs, mean(as.numeric(lang)) >= 3)
# [1] TRUE
list.any(devs, "python" %in% names(lang))
# [1] TRUE

list.count

list.count return a scalar integer that indicates the number of members of a list that satisfy a given condition.

list.count(devs, mean(as.numeric(lang)) >= 3)
# [1] 2
list.count(devs, "r" %in% names(lang))
# [1] 3

list.match

list.match filters a list by matching the names of the list members by a regular expression pattern.

list.match(devs, "p[12]")
# $p1
# $p1$name
# [1] "Ken"
# 
# $p1$age
# [1] 24
# 
# $p1$interest
# [1] "reading" "music"   "movies" 
# 
# $p1$lang
# $p1$lang$r
# [1] 2
# 
# $p1$lang$csharp
# [1] 4
# 
# $p1$lang$python
# [1] 3
# 
# 
# 
# $p2
# $p2$name
# [1] "James"
# 
# $p2$age
# [1] 25
# 
# $p2$interest
# [1] "sports" "music" 
# 
# $p2$lang
# $p2$lang$r
# [1] 3
# 
# $p2$lang$java
# [1] 2
# 
# $p2$lang$cpp
# [1] 5

list.remove

list.remove removes list members by index or name.

list.remove(devs, c("p1","p2"))
# $p3
# $p3$name
# [1] "Penny"
# 
# $p3$age
# [1] 24
# 
# $p3$interest
# [1] "movies"  "reading"
# 
# $p3$lang
# $p3$lang$r
# [1] 1
# 
# $p3$lang$cpp
# [1] 4
# 
# $p3$lang$python
# [1] 2
list.remove(devs, c(2,3))
# $p1
# $p1$name
# [1] "Ken"
# 
# $p1$age
# [1] 24
# 
# $p1$interest
# [1] "reading" "music"   "movies" 
# 
# $p1$lang
# $p1$lang$r
# [1] 2
# 
# $p1$lang$csharp
# [1] 4
# 
# $p1$lang$python
# [1] 3

list.exclude

list.exclude removes list members that satisfy given condition.

list.exclude(devs, "sports" %in% interest)
# $p1
# $p1$name
# [1] "Ken"
# 
# $p1$age
# [1] 24
# 
# $p1$interest
# [1] "reading" "music"   "movies" 
# 
# $p1$lang
# $p1$lang$r
# [1] 2
# 
# $p1$lang$csharp
# [1] 4
# 
# $p1$lang$python
# [1] 3
# 
# 
# 
# $p3
# $p3$name
# [1] "Penny"
# 
# $p3$age
# [1] 24
# 
# $p3$interest
# [1] "movies"  "reading"
# 
# $p3$lang
# $p3$lang$r
# [1] 1
# 
# $p3$lang$cpp
# [1] 4
# 
# $p3$lang$python
# [1] 2

subset

subset is implemented for list object in a way that combines list.filter and list.map. This function basically filters a list while at the same time maps the qualified list member by an expression.

subset(devs,age>=24,name)
# $p1
# [1] "Ken"
# 
# $p2
# [1] "James"
# 
# $p3
# [1] "Penny"
subset(devs,"reading" %in% interest, sum(as.numeric(lang)))
# $p1
# [1] 9
# 
# $p3
# [1] 7