Cleber Borges
2024-Oct-26 19:14 UTC
[R] Help in Recursive Function for steps reconstruction in Clusters Analysis - HCA: Single Link
Hello everybody, I'm trying to build a function to illustrate, in 2D, the sequence of the "Single Link" algorithm (the purpose is merely didactic). The idea is to have the scatter of points on a graph. Iteratively, build the segments (with the "segments()" function, for each step). I simulated a data set "d", and created an object "r" using the command: r <- hclust( dist( d ), met='single' ) My problem: I created a recursive function, "f()", to find the shortest distances. It is defined below. But the return has only one column, while I thought there would be two columns. What I get: ############### # Testing f() f( c(2, 3) )?? #### is the fourth step of hclust ???? [,1] xmd1?? -6 xmd2? -10 xmd1?? -3 xmd1?? -4 xmd2?? -5 What I expected: ################## # xmd1?? xmd2 # -6???? -10 # -3????? -5 # -4????? -5 If anyone can help me with this recursive function, I would appreciate it in advance. I've never used recursion before, so I don't have a good grasp of how it works. Thank you very much in advance, Cleber. All details are below: ######################## d <- scan() ?0.986? 0.900 -1.331? 1.503 -0.220 -0.752 ?0.102 -0.071 -0.171? 0.018 -0.782? 0.490 ?1.154 -0.074 -0.768 -1.529 ?1.761 -1.396 -0.730? 0.910 d <- matrix( d, 10, byrow=T ) r <- hclust( dist( d ), met='single' ) r$merge #????? [,1] [,2] # [1,]?? -4?? -5 # [2,]?? -6? -10 # [3,]?? -3??? 1 # [4,]??? 2??? 3 # [5,]?? -2??? 4 # [6,]?? -8??? 5 # [7,]?? -1?? -7 # [8,]??? 6??? 7 # [9,]?? -9??? 8 f <- function(xmd) { ??? rs <- NULL ??? xmd1 <- 999999999 ??? xmd2 <- 999999999 ??? if (xmd[1] > 0) { ??????? xmd1 <- f(r$merge[ xmd[1], ]) ??? } else { ??????? xmd1 <- xmd[1] ??? } ??? if (xmd[2] > 0) { ??????? xmd2 <- f(r$merge[ xmd[2], ]) ??? } else { ??????? xmd2 <- xmd[2] ??? } ??? return( rbind( rs, rbind( xmd1, xmd2 ) ) ) } # Testing f() f( c(2, 3) ) # result of f() #????? [,1] # xmd1?? -6 # xmd2? -10 # xmd1?? -3 # xmd1?? -4 # xmd2?? -5 # My expectative: # xmd1?? xmd2 # -6???? -10 # -3????? -5 # -4????? -5 # Testing f() ?f( c( 6, 7) ) # result of f() #????? [,1] # xmd1?? -8 # xmd1?? -2 # xmd1?? -6 # xmd2? -10 # xmd1?? -3 # xmd1?? -4 # xmd2?? -5 # xmd1?? -1 # xmd2?? -7 # My expectative: # xmd1?? xmd2 # -8???? -10 # -2???? -10 # -6???? -10 # -3????? -5 # -4????? -5 # -1????? -7
Duncan Murdoch
2024-Oct-26 20:03 UTC
[R] Help in Recursive Function for steps reconstruction in Clusters Analysis - HCA: Single Link
On 2024-10-26 3:14 p.m., Cleber Borges via R-help wrote:> Hello everybody, > > I'm trying to build a function to illustrate, in 2D, the sequence of the > "Single Link" algorithm (the purpose is merely didactic). > > The idea is to have the scatter of points on a graph. > Iteratively, build the segments (with the "segments()" function, for > each step). > > I simulated a data set "d", and created an object "r" using the command: > > r <- hclust( dist( d ), met='single' ) > > My problem: > > I created a recursive function, "f()", to find the shortest distances. > It is defined below. > But the return has only one column, while I thought there would be two > columns. >I suspect you used rbind() where you should have used cbind() in your f, here:> ??? return( rbind( rs, rbind( xmd1, xmd2 ) ) )which should have been return( rbind( rs, cbind( xmd1, xmd2 ) ) ) There may be other places where this change is needed; I haven't tried running your code. Duncan Murdoch
Cleber Borges
2024-Oct-26 21:46 UTC
[R] Help in Recursive Function for steps reconstruction in Clusters Analysis - HCA: Single Link
For now, I've been able to think of a temporary solution... until I can think of a better teaching solution: The same function f(): ##### f <- function(xmd) { ??? rs <- NULL ??? xmd1 <- 999999999 ??? xmd2 <- 999999999 ??? if (xmd[1] > 0) { ??????? xmd1 <- f(r$merge[ xmd[1], ]) ??? } else { ??????? xmd1 <- xmd[1] ??? } ??? if (xmd[2] > 0) { ??????? xmd2 <- f(r$merge[ xmd[2], ]) ??? } else { ??????? xmd2 <- xmd[2] ??? } ??? return( rbind( rs, rbind( xmd1, xmd2 ) ) ) } #### Didactic example to illustrate the chain behavior of the "Single Link" Algorithm n <- 100 d <- matrix( runif( n * 2 ), n, 2 ) r <- hclust( dist( d ), met='single' ) plot( d, cex=1, col=1 ) for( i in 1:( nrow( d ) - 1 ) ){ ??? p <- as.numeric( abs( f( r$merge[ i, ] ) ) ) ??? points( d[ p,], col=i, cex=2, pch=19 ) ??? cat(' Step: ', i, '\n' ) ??? flush.console() ??? Sys.sleep( .2 ) } Em 26/10/2024 16:14, Cleber Borges escreveu:> Hello everybody, > > I'm trying to build a function to illustrate, in 2D, the sequence of > the "Single Link" algorithm (the purpose is merely didactic). > > The idea is to have the scatter of points on a graph. > Iteratively, build the segments (with the "segments()" function, for > each step). > > I simulated a data set "d", and created an object "r" using the command: > > r <- hclust( dist( d ), met='single' ) > > My problem: > > I created a recursive function, "f()", to find the shortest distances. > It is defined below. > But the return has only one column, while I thought there would be two > columns. > > > What I get: > ############### > # Testing f() > f( c(2, 3) )?? #### is the fourth step of hclust > > ???? [,1] > xmd1?? -6 > xmd2? -10 > xmd1?? -3 > xmd1?? -4 > xmd2?? -5 > > What I expected: > ################## > > # xmd1?? xmd2 > # -6???? -10 > # -3????? -5 > # -4????? -5 > > > If anyone can help me with this recursive function, I would appreciate > it in advance. > I've never used recursion before, so I don't have a good grasp of how > it works. > > Thank you very much in advance, > > Cleber. > > > > All details are below: > ######################## > > > d <- scan() > ?0.986? 0.900 > -1.331? 1.503 > -0.220 -0.752 > ?0.102 -0.071 > -0.171? 0.018 > -0.782? 0.490 > ?1.154 -0.074 > -0.768 -1.529 > ?1.761 -1.396 > -0.730? 0.910 > > d <- matrix( d, 10, byrow=T ) > > r <- hclust( dist( d ), met='single' ) > r$merge > #????? [,1] [,2] > # [1,]?? -4?? -5 > # [2,]?? -6? -10 > # [3,]?? -3??? 1 > # [4,]??? 2??? 3 > # [5,]?? -2??? 4 > # [6,]?? -8??? 5 > # [7,]?? -1?? -7 > # [8,]??? 6??? 7 > # [9,]?? -9??? 8 > > > f <- function(xmd) { > > ??? rs <- NULL > ??? xmd1 <- 999999999 > ??? xmd2 <- 999999999 > > ??? if (xmd[1] > 0) { > ??????? xmd1 <- f(r$merge[ xmd[1], ]) > ??? } else { > ??????? xmd1 <- xmd[1] > ??? } > > ??? if (xmd[2] > 0) { > ??????? xmd2 <- f(r$merge[ xmd[2], ]) > ??? } else { > ??????? xmd2 <- xmd[2] > ??? } > > ??? return( rbind( rs, rbind( xmd1, xmd2 ) ) ) > } > > > > # Testing f() > f( c(2, 3) ) > > # result of f() > #????? [,1] > # xmd1?? -6 > # xmd2? -10 > # xmd1?? -3 > # xmd1?? -4 > # xmd2?? -5 > > # My expectative: > # xmd1?? xmd2 > # -6???? -10 > # -3????? -5 > # -4????? -5 > > > # Testing f() > ?f( c( 6, 7) ) > > # result of f() > #????? [,1] > # xmd1?? -8 > # xmd1?? -2 > # xmd1?? -6 > # xmd2? -10 > # xmd1?? -3 > # xmd1?? -4 > # xmd2?? -5 > # xmd1?? -1 > # xmd2?? -7 > > > # My expectative: > # xmd1?? xmd2 > # -8???? -10 > # -2???? -10 > # -6???? -10 > # -3????? -5 > # -4????? -5 > # -1????? -7 >