## Example 1
## general
# two lists
list1 <- list(a = 1:10, b = FALSE)
list2 <- list(b = TRUE, c = "new")
# updating a with b
# keeps unchanged list1 entry, a
# updates changed list1 entry, b
# adds new (list2) entry, c
listUpdate(list1, list2)
## Example2
## use in plot functions
## to simplify formals
if (FALSE) {
# some data
a <- 1:10
b <- rnorm(10,5,2)
#a bad plot function
badplot <- function(x, ...){
#setting defaults in xyplot call itself
xyplot(x = x, pch = 20, col = "red",
panel = function(...){
panel.grid(-1, -1)
panel.xyplot(...)
panel.abline(0,1)
}, ...)
}
badplot(a~b) #OK
# compare with
badplot(a~b, xlim = c(1,20)) #OK
badplot(a~b, col = "blue") #not OK
# because col hardcoded into badplot function
# It is duplicated in call and '...'
# so user cannot update col
#a standard correction
stdplot <- function(x, pch = 20, col = "red", ...){
#setting defaults in xyplot call itself
xyplot(x = x, pch = 20, col = "red",
panel = function(x=x, pch=pch, col=col, ...){
panel.grid(-1, -1)
panel.xyplot(x=x, pch=pch, col=col, ...)
panel.abline(0,1)
}, ...)
}
stdplot(a~b) #OK
stdplot(a~b, col = "blue",
xlim=c(1:20)) #also OK
# An alternative correction using lists and
# listUpdate that removes the need for formal
# definition of all modified plot arguments
myplot <- function(x, ...){
#defaults I set for myplot form of xyplot
mylist <- list(x = x, pch = 20, col = "red",
panel = function(...){
panel.grid(-1, -1)
panel.xyplot(...)
panel.abline(0,1)
})
#plot
do.call(xyplot, listUpdate(mylist, list(...)))
}
myplot(a~b) #OK
myplot(a~b, col = "blue",
xlim = c(1,20)) #also OK
}
Run the code above in your browser using DataLab