[R] Recursive function calls
Hadley Wickham
hadley at rice.edu
Fri Aug 3 22:52:00 CEST 2012
On Fri, Aug 3, 2012 at 12:19 PM, Rui Barradas <ruipbarradas at sapo.pt> wrote:
> Hello,
>
> This seems to work.
>
> trim2 <- function(x) {
> if(is.atomic(x))
>
> gsub("^[[:space:]]+|[[:space:]]+$", "", x)
> else
> sapply(x, function(y) trim2(y))
> }
>
Using sapply is a bit dangerous here. Compare:
trim2(list(c("a", "b"), c("c", "d")))
# [,1] [,2]
# [1,] "a" "c"
# [2,] "b" "d"
trim2(list(c("a", "b"), c("c", "d", "e")))
# [[1]]
# [1] "a" "b"
#
# [[2]]
# [1] "c" "d" "e"
which I think is rather undesirable behaviour. sapply is suitable for
interactive use, but you should never use it inside a function because
you don't know what sort of data structure you'll get back.
I think it's also a bit unsafe to accept any type of input - you're
generally better off being explicit. This leads to trim3:
trim3 <- function(x) {
if (is.character(x)) {
gsub("^[[:space:]]+|[[:space:]]+$", "", x)
} else if (is.list(x)) {
lapply(x, trim3)
} else {
warning("Invalid input: ", paste(class(x), sep = "/"))
x
}
}
trim2(list(c("a", "b"), c("c", "d")))
trim3(list(c("a", "b"), c("c", "d")))
But then the function isn't extensible for new types of input, which
suggests an S3 implementation:
trim4 <- function(x) UseMethod("trim4")
trim4.character <- function(x) gsub("^[[:space:]]+|[[:space:]]+$", "", x)
trim4.list <- function(x) lapply(x, trim4)
trim4.default <- function(x) {
warning("Invalid input")
x
}
Hadley
--
Assistant Professor / Dobelman Family Junior Chair
Department of Statistics / Rice University
http://had.co.nz/
More information about the R-help
mailing list