[18668] in s-news-athena

home help back first fref pref prev next nref lref last post

[S] "Eliminating a for loop" -Partial- Summary of Replies

daemon@ATHENA.MIT.EDU (Barker, Chris {PHAR~Palo Alto})
Mon Jul 19 14:15:33 1999

Content-Return: allowed
Date: Mon, 19 Jul 1999 11:08:07 -0700
From: "Barker, Chris {PHAR~Palo Alto}" <CHRIS.BARKER@ROCHE.COM>
To: "'s-news@wubios.wustl.edu'" <s-news@wubios.wustl.edu>
Message-Id: <B9E51B9719BDD111AB640000F80197CDBEB742@rplmsem2.pal.roche.com>
Mime-Version: 1.0
Content-Type: text/plain; CHARSET=US-ASCII



Many thanks those who replied to my question! 
I had promised to summarize the replies. Because I've received 18 replies,
somewhat arbitrarily, 
I've provided only 4 of the replies below (my apology to the other
individuals). 
_________________________________________________________________________
On a side note: my question arose because I was trying to "fill in missing
longitundinal data" 
so that I could  plot longitudinal data using a groupedData object.  
Doug Bates advises that:
"Look at the Quinidine data in the NLMEDATA library.  Most of the rows
have missing data for the response (conc) but you can still plot it."

_________________________________________________________________________
----Algorithms-----------------------------------------------------

(Lastly I haven't tested these algorithms!)


From Bill Dunlap at Mathsoft:

A partial solution may be in the following function, which is given a
logical vector (is.na(data) in your case) and returns a vector of
indices into that vector.  The indices give the index of the last FALSE
value in the vector for each element of the vector.  E.g.,

   >  x <- c(11,NA,NA,14,15,NA)
   > f2(is.na(x))
   [1] 1 1 1 4 5 5
   > x[f2(is.na(x))]   # replace NA's by last non-NA
   [1] 11 11 11 14 15 15

   f2 <- function(x)
   {
           if(!is.logical(x))
                   stop("x must be a logical vector")
           if(x[1])
                   stop("First element of x must not be TRUE")
           val <- seq(along = x)
           val[x] <- 0
           val[!x][-1] <- diff(val[!x])
           cumsum(val)
   }

It is a lot faster than the naive (loopy) version in f0:

   f0 <- function(x) {
           if(!is.logical(x))
                   stop("x must be a logical vector")
           if(x[1])
                   stop("First element of x must not be TRUE")
           val <- seq(along = x)
           for(i in seq(along = x)[-1])
                   if(x[i]) val[i] <- val[i - 1]
              val
   }

You may get further improvements by modifing it (and the replacement
code that uses it) to only replace items that will be changed instead
of replacing all of them.
____________________________________________________________________________
_____________________
____________________________________________________________________________
________________________
From Bill Venables:
Your code assumes that if you pull out all 21 records for each patient they
will be in sorted order by day.  Let's guarantee that in the imputed data
frame the records for each patient are contiguous:

> RawData.imputed <- RawData[order(pt), ]

(This may not be necessary if as I suspect the daily records within patient
are already contiguous.)

Now pull out the variable you are interested in, do the adjustment, and put
it back again:

> nos <- 1:rnow(RawData.imputed)
> var.day <- RawData.imputed$var.day
> while(any(NAs <- is.na(var.day))) {
+	which <- nos[NAs]
+	var.day[which] <- var.day[which - 1]
+ }
> RawData.imputed$var.day <- var.day

_______________________________________________________________
From Charles Berry:
for (i in 2:21) 
	RawData[is.na(RawData[,i]),i] <- RawData[is.na(RawData[,i]),i-1]
	
____________________________________________________________________
From Jean Adams

     # sort the data frame by patient, day
     temp.frame.sort <- temp.frame[order(pt, temp.frame$var.day), ]
     
     # assign to every NA in var.day, the last value for the vector
     x <- temp.frame.sort$var.day
     y <- x
     last <- x[1]
     for(i in 2:length(y)) if(is.na(x[i])) y[i] <- last else last <- x[i]
     temp.frame.sort$var.day <- y

Chris Barker, Ph.D.
Principal Pharmacoeconomic Statistician
Roche Pharma Business - Palo Alto
(650)-852-3152

-----------------------------------------------------------------------
This message was distributed by s-news@wubios.wustl.edu.  To unsubscribe
send e-mail to s-news-request@wubios.wustl.edu with the BODY of the
message:  unsubscribe s-news

home help back first fref pref prev next nref lref last post