recursion - How to utilize recursive functions to help rank matrix rows - R -
recursion - How to utilize recursive functions to help rank matrix rows - R -
i advice how best solve puzzle. have got of way solving using manually written long-hand code. sense if need utilize recursive functions, still not @ using them. hope question not long, i'm trying succinct possible whilst giving plenty information. sorry if it's long - though finds of interest.
i have matrix mat1
# b c d e f g # 0 2 1 1 0 1 1 # b 0 0 0 1 2 2 1 # c 1 2 0 0 0 2 1 # d 1 1 2 0 1 2 1 # e 2 0 2 1 0 2 1 # f 1 0 0 0 0 0 1 # g 1 1 1 1 1 1 0
this represents results of contests between individuals in rows , columns. numbers refer how individual in row 'won' against individual in column.
i wish rank individuals a-g 1-7 using next criteria:
number of wins against others (most wins should ranked 1, to the lowest degree wins 7, 2nd wins 2, etc.)
if number of wins tied, ranks should based on number of wins obtained when considering contests between individuals same number of wins.
if individuals still have tied number of wins, ranks should applied randomly.
i realize not ranking system, that's not issue here. according above scheme, ranks should following:
1 - d or e - d & e have joint highest overall wins (8), , equal wins in contests between them. 2 - e or d - pick randomly d or e rank 1 , rank 2 3 - or c - tied a,b,c,g overall 6 wins, both have 4 wins in contents abcg 4 - c or - considering contests between c&a both have 1 win, randomly pick rank3 , rank4 5 - g - tied a,b,c,g overall 6 wins, has 3 wins in contests between a,b,c,g 6 - b - tied a,b,c,g overall 6 wins, has 1 win in contests between a,b,c,g 7 - f - has fewest wins of in overall win matrix what have tried:storeresults <- vector("list") #use store results of next
step 1: utilize winsfun
function (see below) identify number of wins of each individual & whether wins unique (as noted dupes column):
w1 <- winsfun(mat1) storeresults[[1]] <- w1 #store results
w1
"f" has unique number of wins , can ranked (7th) in first instance:
# wins ranks dupes #a 6 4.5 true #b 6 4.5 true #c 6 4.5 true #d 8 1.5 true #e 8 1.5 true #f 2 7.0 false #g 6 4.5 true
step 2: individuals non-unique wins (i.e. duplicated ranks) subset them matrices considering contests against others same number of wins, , determine new ranks if possible.
allsame(w1[,3]) #false - says not wins/ranks unique need subset s2 <- subsetties(w1) #this splits info groups number of wins (see below) w2 <- lapply(s2, winsfun, m=mat1) storeresults[[2]] <- w2 # store results
w2
can seen, individuals 8 wins (the of anyone) step1 ("d" , "e") each have 1 win versus each other. cannot teased apart, ranked 1 , 2 randomly. individuals 6 wins (a, b, c, g) have different number of wins when considering contests between each other. "b" , "g" can ranked 6th overall , 5th overall respectively. need reconsider "a" , "c" in contests against each other:
$`6` wins ranks dupes 4 1.5 true b 1 4.0 false c 4 1.5 true g 3 3.0 false $`8` wins ranks dupes d 1 1.5 true e 1 1.5 true
step 3: repeat step 2 required
allsame(w2[[1]][,3]) #false - need subset 1 time again not has same number of wins allsame(w2[[2]][,3]) #true - no more action required s3 <- subsetties(w2[[1]]) w3 <- winsfun(s3[[1]], m=mat1) storeresults[[3]] <- w3 #store results
w3
when considering "a" , "c" together, have 1 win each, should ranked randomly in 2nd , 3rd place. cannot teased apart.
wins ranks dupes 1 1.5 true c 1 1.5 true allsame(w3[,3]) #true - no more action required - both have same number of wins
step 4 processing stored results
storeresults # can manually work out ranks this, have yet work out how in r
below functions used in above:
function calculate wins , ranks of subsetted matrices
winsfun <- function(m, out=null){ if (is.null(out)==f){ m1 <- m[rownames(out),rownames(out)] wins <- apply(m1, 1, sum) ranks <- rank(-wins) dupes <- duplicated(wins)| duplicated(wins, fromlast = t) df <- data.frame(wins, ranks,dupes) return(df) } else wins <- apply(m, 1, sum) ranks <- rank(-wins) dupes <- duplicated(wins)| duplicated(wins, fromlast = t) df <- data.frame(wins, ranks,dupes) return(df) }
function subset rows duplicated ranks
subsetties <- function(df){ df1 <- df[df[,3]==t,] df1.sp <- split(df1, df1$wins) return(df1.sp) }
function test if elements of vector identical
allsame <- function(x) length(unique(x)) == 1
code recreate above matrix:
structure(c(0, 0, 1, 1, 2, 1, 1, 2, 0, 2, 1, 0, 0, 1, 1, 0, 0, 2, 2, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 2, 0, 1, 0, 0, 1, 1, 2, 2, 2, 2, 0, 1, 1, 1, 1, 1, 1, 1, 0), .dim = c(7l, 7l), .dimnames = list( c("a", "b", "c", "d", "e", "f", "g"), c("a", "b", "c", "d", "e", "f", "g")))
i hope question clear. trying work out how perform algorithm iteratively. not sure how accomplish this, writing out long-hand , providing functions have been using, may obvious somebody. 1 thing it's best have proposed solution applicable (i.e. matrices of different sizes).
calc_gain<-function(mat=mat1){ if(nrow(mat)==1) { return(row.names(mat)) } else { classement<-sort(rowsums(mat),decreasing=t) diffgains<-diff(classement) if (all(diffgains!=0)){ return(names(classement)) } else { if (all(diffgains==0)){ return(sample(names(classement))) } else { parex<-split(classement,factor(classement,levels=unique(classement))) class_parex<-lapply(parex,function(vect){calc_gain(mat[names(vect),names(vect),drop=f])}) return(unlist(class_parex)) } } } }
here function :
if there 1 element, returns name of (only "player" there is) else, calculates scores. if there no tie, returns "players" in order first last else, - if "players" have same score, randomly gives order. else, splits ordered list according scores , apply function (that recursive part) on subsets of "players" tied scores. r recursion matrix
Comments
Post a Comment