Skip to content

loop function within a loop

4 messages · Sally Zhen, Weidong Gu, David Winsemius +1 more

#
It's better to avoid loop in this situation. If you want to reorder
subsets of the data based on event, the follow works

df<-read.table('clipboard',header=TRUE)
sp.or<-lapply(split(df,df$group),function(ldf) ldf[order(ldf$event),])
new.df<-do.call('rbind',sp.or)

Weidong Gu
On Wed, Oct 12, 2011 at 10:55 AM, Sally Zhen <saliluna at gmail.com> wrote:
#
On Oct 12, 2011, at 10:55 AM, Sally Zhen wrote:

            
Not generally a good first strategy in R.
Wouldn't this just be:

dfrm[order(dfrm$group, dfrm$event), ]

(Ascending is the default ordering.)
#
Is this the result you are after, where the event number
(within a group) are sorted according to the event/prev_event
pairs (prev_event in a row matches event of the previous row)?
event prev_event group
1    845          0  5360
2    234        845  5360
3    993        234  5360
4    153        993  5360
5    926        153  5360
6    848        926  5360
7    234          0  8765
8    968        234  8765
9    545        968  8765
10   625        111  3334
11   713        625  3334
12   227        713  3334
13   181        227  3334
14   744        181  3334
15   913          0  2329
16   355        913  2329
17   761        355  2329
18   324        761  2329
19   119        324  2329
20   372        119  2329
21   890        372  2329
22   189        890  2329
23   719        189  2329
24   266        719  2329

'tsort' is a topological sorting function, like
the Unix tsort.  It is overkill for this application
(and probably could be faster and do some more
error checking) but I had it hanging around:

tsort <- function (before, after) 
{
    # topological sort: Kahn's 1962 algorithm, from Wikipedia 
    # before and after should be equal-length vectors of the
    # same type.
    L <- before[0]
    S <- setdiff(before, after)
    while (length(S) > 0) {
        n <- S[1]
        S <- S[-1]
        L[length(L) + 1] <- n
        m <- after[e <- before == n]
        after <- after[!e]
        before <- before[!e]
        S <- c(S, m[!is.element(m, after)])
    }
    if (length(after) > 0) {
        stop("Graph contains a cycle")
    }
    else {
        L
    }
}

Your data was

d <- data.frame(
  event = c(845, 926, 993, 234, 848, 153, 234, 968, 545, 625, 744, 181, 
    713, 227, 913, 372, 719, 119, 761, 890, 266, 324, 189, 355),
  prev_event = c(0, 153, 234, 845, 926, 993, 0, 234, 968, 111, 181, 227, 625, 
    713, 0, 119, 189, 324, 355, 372, 719, 761, 890, 913),
  group = c(5360, 5360, 5360, 5360, 5360, 5360, 8765, 8765, 8765, 3334, 
    3334, 3334, 3334, 3334, 2329, 2329, 2329, 2329, 2329, 2329, 2329, 
    2329, 2329, 2329))

Bill Dunlap
Spotfire, TIBCO Software
wdunlap tibco.com