[R] recursive function, how to avoid list structure in return value
Jenny Bryan
jenny at stat.ubc.ca
Fri Apr 10 21:32:51 CEST 2009
I've written a recursive function to extract the members of an
individual cluster within a hierarchical clustering. I have something
that works, but the return value has a list structure I don't like. I
know how to work around with 'unlist()' but I suspect the function
could be fixed. Can anyone show me show?
Thanks,
Jenny Bryan
Demo of my problem --
(Note: although my question has nothing to do with hierarchical
clustering per se, my example does assume knowledge of the 'merge'
object.)
## faking the key aspects of an hclust object
myClust <-
list(merge = rbind(c(-1, -2),
c(-3, -4),
c(2, -5),
c(1, 3),
c(4, -6)),
height = 1:5,
order = 1:6)
## plot the example / fake tree
stats:::plot.hclust(myClust, hang = -1)
## recursive function to extract members of a cluster
## 'sapply' version
clMembFun1 <- function(x) {
if(x < 0) {
-x
} else {
sapply(1:2, function(j) clMembFun1(myClust$merge[x,j]))
}
}
Here's a transcript of using clMembFun:
> ## trivial case of cluster = 2 singletons is OK
> clMembFun1(1)
[1] 1 2
> str(clMembFun1(1)) # num vector
num [1:2] 1 2
> ## case of cluster that contains a cluster --> list
> clMembFun1(3)
[[1]]
[1] 3 4
[[2]]
[1] 5
> str(clMembFun1(3))
List of 2
$ : num [1:2] 3 4
$ : num 5
> ## now the list also has 2D matrix structure
> clMembFun1(4)
[,1] [,2]
[1,] 1 Numeric,2
[2,] 2 5
> str(clMembFun1(4))
List of 4
$ : num 1
$ : num 2
$ : num [1:2] 3 4
$ : num 5
- attr(*, "dim")= int [1:2] 2 2
> ## and it just gets worse
> clMembFun1(5)
[[1]]
[,1] [,2]
[1,] 1 Numeric,2
[2,] 2 5
[[2]]
[1] 6
> str(clMembFun1(5))
List of 2
$ :List of 4
..$ : num 1
..$ : num 2
..$ : num [1:2] 3 4
..$ : num 5
..- attr(*, "dim")= int [1:2] 2 2
$ : num 6
I know one workaround is to 'unlist' the return value:
> ## post hoc fix
> unlist(clMembFun1(3))
[1] 3 4 5
> unlist(clMembFun1(4))
[1] 1 2 3 4 5
> unlist(clMembFun1(5))
[1] 1 2 3 4 5 6
But can the function itself be fixed/improved?
I also tried using a 'for' loop instead of 'sapply' but that suffered
from fatal problems (maybe I didn't implement correctly?).
More information about the R-help
mailing list