rlist is a set of tools for working with list objects. It has two main goals:
Install from CRAN with
install.packages("rlist")
or install the latest development version from GitHub with
devtools::install_github("rlist","renkun-ken")
A wide range of functions are provided to work with list objects.
Suppose we have a list of developers, each of which has a name, age, some interests and a list of programming language they use and the number of years they have been using them.
library(rlist)
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)))
Filter members whose age is no less than 25 by calling list.filter
.
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
Get the name of each person by calling list.map
that maps each member by an expression.
list.map(devs, name)
# $p1
# [1] "Ken"
#
# $p2
# [1] "James"
#
# $p3
# [1] "Penny"
Get the programming language each person has been using for the longest time by calling list.map
.
list.map(devs, sort(unlist(lang),decreasing = T)[1])
# $p1
# csharp
# 4
#
# $p2
# cpp
# 5
#
# $p3
# cpp
# 4
Select the name and age of each member by calling list.select
.
str(list.select(devs,name,age))
# List of 3
# $ p1:List of 2
# ..$ name: chr "Ken"
# ..$ age : num 24
# $ p2:List of 2
# ..$ name: chr "James"
# ..$ age : num 25
# $ p3:List of 2
# ..$ name: chr "Penny"
# ..$ age : num 24
Select the name and evaluate the range of the number of years using programming languages.
str(list.select(devs,name,score.range=range(unlist(lang))))
# List of 3
# $ p1:List of 2
# ..$ name : chr "Ken"
# ..$ score.range: num [1:2] 2 4
# $ p2:List of 2
# ..$ name : chr "James"
# ..$ score.range: num [1:2] 2 5
# $ p3:List of 2
# ..$ name : chr "Penny"
# ..$ score.range: num [1:2] 1 4
Build a list that contains sublists each represents an age group by calling list.group
.
str(list.group(devs,age))
# List of 2
# $ 24: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
# ..$ p3:List of 4
# .. ..$ name : chr "Penny"
# .. ..$ age : num 24
# .. ..$ interest: chr [1:2] "movies" "reading"
# .. ..$ lang :List of 3
# .. .. ..$ r : num 1
# .. .. ..$ cpp : num 4
# .. .. ..$ python: num 2
# $ 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
Sort the developers by the number of interests in descending order, then by the number of years they have been using R in descending order by calling list.sort
.
sorted <- list.sort(devs,desc(length(interest)),desc(lang$r))
list.map(sorted,name)
# $p1
# [1] "Ken"
#
# $p2
# [1] "James"
#
# $p3
# [1] "Penny"
Use list.update
to update the list by removing age
and lang
columns and introducing the number of languages each member uses as nlang
.
str(list.update(devs,age=NULL,lang=NULL,nlang=length(lang)))
# List of 3
# $ p1:List of 3
# ..$ name : chr "Ken"
# ..$ interest: chr [1:3] "reading" "music" "movies"
# ..$ nlang : int 3
# $ p2:List of 3
# ..$ name : chr "James"
# ..$ interest: chr [1:2] "sports" "music"
# ..$ nlang : int 3
# $ p3:List of 3
# ..$ name : chr "Penny"
# ..$ interest: chr [1:2] "movies" "reading"
# ..$ nlang : int 3
Much more functions are provided than the examples show. Please read the documentation of the package.
Pipeline operators may hugely improve the readability of the code especially when a chain of commands are executed. pipeR package is recommended to co-work with this package.
If we want to know the developers whose age is no more than 24 and create a data frame where they are sorted by the number of years using R in descending order and each row tells us the name, years of using R, and the longest time using a language they know.
library(pipeR)
devs %>>%
list.filter(age <= 24) %>>%
list.sort(desc(lang$r)) %>>%
list.map(data.frame(name=name,r=lang$r,
longest=max(unlist(lang)))) %>>%
list.rbind
# name r longest
# p1 Ken 2 4
# p3 Penny 1 4
Most functions in this package supports lambda expressions like x ~ f(x)
or x -> f(x)
where x
refers to the list member itself. Otherwise, .
will by default be used to represent it.
nums <- list(a=c(1,2,3),b=c(2,3,4),c=c(3,4,5))
nums %>>%
list.map(data.frame(min=min(.),max=max(.))) %>>%
list.rbind
# min max
# a 1 3
# b 2 4
# c 3 5
nums %>>%
list.map(x ~ sum(x))
# $a
# [1] 6
#
# $b
# [1] 9
#
# $c
# [1] 12
nums %>>%
list.filter(x -> mean(x)>=3)
# $b
# [1] 2 3 4
#
# $c
# [1] 3 4 5
help(package = rlist)
This package is under MIT License.