[R] apply a function down each column

David Winsemius dwinsemius at comcast.net
Mon Jan 11 15:49:58 CET 2010


On Jan 11, 2010, at 9:18 AM, Steve Lianoglou wrote:

> Hi,
>
> On Mon, Jan 11, 2010 at 8:41 AM, Laetitia Schmid  
> <laetitia at gmt.su.se> wrote:
>> Hello World,
>> I have a function that makes pairwise comparisons between two  
>> strings. I would like to apply this function to my data (which  
>> consists of columns with different strings) in the way that it  
>> compares the first with the second entry, and then the third with  
>> the fourth, and then the fifth with the sixth, and so on down each  
>> column...
>> So (2x-1) and (2x) would be the different entries to be compared!
>>
>> dat= my data:
>>
>> for the first column: compare dat[(2x-1),1] with dat[(2x),1] and x  
>> would be 1:i, i=length(dat[,1])
>>
>> I think the best way to do that is a loop:
>>
>> a <- as.character(dat[(2x-1),1])
>> b <- as.character(dat[(2x),1])
>>
>> for (i in 1:length(dat[,1]) my_function(a, b))
>>
>> Can somebody help me to apply a function with a loop in the way I  
>> want to a column?
>
> It seems as if you got it already, don't you?
>
> for (x in 1:(nrow(dat)-1)) {
>  a <- dat[(2x-1),1]
>  b <- dat[(2x), 1]
>  my_function(a,b)
> }
>
>> Is there a specification of "tapply" for that?

library(zoo)
?rollapply

 > dat <- letters[sample(1:20)]
 > dat
  [1] "l" "d" "o" "s" "j" "k" "t" "r" "g" "b" "e" "q" "f" "i" "c" "n"  
"m" "p" "a" "h"
# using "<" as a pairwise comparison as an example
 > zdat <- zoo(dat, as.Date(1:20))
 > rollapply(zdat, width=2, FUN=function(x) {x[1] < x[2]} , by=2)
1970-01-02 1970-01-04 1970-01-06 1970-01-08 1970-01-10 1970-01-12  
1970-01-14 1970-01-16 1970-01-18 1970-01-20
      FALSE       TRUE       TRUE      FALSE      FALSE        
TRUE       TRUE       TRUE       TRUE       TRUE

The date labels are arbitrary. If youy want them to be removed you can  
wrap as.vector() around the rollapply call.


>
> I don't think so, but depending on what you want to do, the size of
> your data, and the amount of RAM you have, it might be faster to
> compare everything "at once" (assuming `my_function` can be
> vectorized), for instance:
>
> a <- dat[seq(1, nrow(dat), by=2),1]
> b <- dat[seq(2, nrow(dat), by=2), 1]
> all.results <- my_function(a,b)
>
> Also, as an aside, I see you keep calling "as.character" on your data
> when you extract it from your data.frame. Is your data being converted
> to factors? You can look to set stringsAsFactors=FALSE if this is the
> case and you are reading in data using read.table/delim/etc (see:
> ?read.table)
>
> Hope that helps,
>
> -steve
>
> -- 
> Steve Lianoglou
>

David Winsemius, MD
Heritage Laboratories
West Hartford, CT



More information about the R-help mailing list