[R] question about getting things out of an lapply

Joshua Wiley jwiley.psych at gmail.com
Thu Jul 7 17:40:11 CEST 2011


Dear Annemarie,

Look at what you are passing to your function:

lapply(tree$edge, print)

I am guessing you want to be passing:

lapply(1:nrow(tree$edge), print)

so that you are using each row of tree$edge.  Also, take a look at the
code below for some examples of ways you can simplify (and vastly
speed) your task if what I said above is true.  The final version does
your function and saves the results in just three lines without even
creating a special function.

Hope this helps,

Josh

################################
library(ape)
library(plotrix)

## Shortened data creation
tree <- rtree(15)
data <- rnorm(15, mean = 0.5, sd = 0.15)
data <- c(data, ace(data, tree)$ace)
names(data) <- NULL

## original function
create.gradient <- function(i){
colorgrad01<-color.scale(seq(0,1,by=0.01), extremes=c("red","blue"))

tree$edge[i,1] -> x
tree$edge[i,2] -> y
print(x)
print(y)
data[x] -> z
data[y] -> z2

round(z, digits = 2) -> z
round(z2, digits = 2) -> z2
z*100 -> z
z2*100 -> z2
print(z)
print(z2)
colorgrad<-colorgrad01[z:z2]
colorgrad
}

## Store results
## note that rather than using tree$edge direction
## I am using 1:nrow(tree$edge), I think that is what you want
out <- lapply(1:nrow(tree$edge), create.gradient)


## simplified version of above function
create.gradient2 <- function(i) {
  colorgrad01 <- color.scale(seq(0, 1, by = 0.01), extremes = c("red", "blue"))
  z <- round(data[tree$edge[i, ]], 2) * 100
  print(z)
  colorgrad01[z[1]:z[2]]
}

## Store results
out2 <- lapply(1:nrow(tree$edge), create.gradient2)


## even more simplified
colours <- color.scale(seq(0, 1, by = 0.01), extremes = c("red", "blue"))
index <- matrix((round(data, 2) * 100)[tree$edge], ncol = 2)
## store results
out3 <- lapply(1:nrow(tree$edge), function(x) colours[index[x, 1]:index[x, 2]])

## test whether results of all three ways are identical
all(identical(out, out2), identical(out, out3))

## So whats the value of the different versions?
## Besides simplicity of code, here is how long 1000 replications
## of each version took on my (rather slow) laptop

## Version 1 (original)
   user  system elapsed
  61.76    0.27   62.42
## Version 2 (simplified quantity of code)
   user  system elapsed
  54.82    0.25   59.26
## Version 3 (almost completely vectorized)
   user  system elapsed
   0.42    0.01    0.45

On Thu, Jul 7, 2011 at 4:25 AM, Annemarie Verkerk
<annemarie.verkerk at mpi.nl> wrote:
> Dear Josh,
>
> thanks for pointing this out - the idea behind writing this function is
> plotting gradients on branches of phylogenetic trees - 'tree' refers to a
> phylogenetic tree. It's easy to create a random phylogenetic tree in R:
>
> library(ape)
> library(plotrix)
>
> rtree(15) -> tree
>
> This gives you a tree with 15 taxa. You can plot it with plot() if you want
> to take a look.
>
> then the data - you can create a fake data set:
>
> rnorm(15, mean = 0.5, sd = 0.15) -> data
>
> for the data which the function needs, you also need:
>
> ace(data, tree) -> results
>
> data <- append(data,results$ace)
>
> names(data) <- NULL
>
> I also tried with the following updated code I still got the same error
> message:
>
> create.gradient <- function(i){
> colorgrad01<-color.scale(seq(0,1,by=0.01), extremes=c("red","blue"))
> tree$edge[i,1] -> x
> tree$edge[i,2] -> y
> print(x)
> print(y)
> data[x] -> z
> data[y] -> z2
> round(z, digits = 2) -> z
> round(z2, digits = 2) -> z2
> z*100 -> z
> z2*100 -> z2
> print(z)
> print(z2)
> colorgrad<-colorgrad01[z:z2]
> colorgrad
> }
>
> lapply(tree$edge, create.gradient)
>
> - Error in FUN(X[[26L]], ...) : subscript out of bounds
>
> I hope this help and you can replicate the problem too.
>
> Thanks!
> Annemarie
>
> Joshua Wiley wrote:
>>
>> Dear Annemarie,
>>
>> Can you replicate the problem using a madeup dataset or one of the
>> ones built into R?  It strikes me as odd to pass tree1$edge directly
>> to lapply, when it is also hardcoded into the function, but I do not
>> have a sense exactly for what you are doing and without data it is
>> hard to play around.
>>
>> Cheers,
>>
>> Josh
>>
>> On Wed, Jul 6, 2011 at 12:31 PM, Annemarie Verkerk
>> <annemarie.verkerk at mpi.nl> wrote:
>>
>>>
>>> Dear R-help subscribers,
>>>
>>> I have a quite stupid question about using lapply. I have the following
>>> function:
>>>
>>> create.gradient <- function(i){
>>> colorgrad01<-color.scale(seq(0,1,by=0.01), extremes=c("red","blue"))
>>> tree1$edge[i,1] -> x
>>>
>>
>> this works, but it would typically be written:
>>
>> x <- tree1$edge[i, 1]
>>
>> flipping back and forth can be a smidge (about 5 pinches under an
>> iota) confusing.
>>
>>
>>>
>>> tree1$edge[i,2] -> y
>>> print(x)
>>> print(y)
>>> all2[x] -> z
>>> all2[y] -> z2
>>> round(z, digits = 2) -> z
>>> round(z2, digits = 2) -> z2
>>> z*100 -> z
>>> z2*100 -> z2
>>> print(z)
>>> print(z2)
>>> colorgrad<-colorgrad01[z:z2]
>>> colorgrad
>>> }
>>>
>>> Basically, I want to pick a partial gradient out of a bigger gradient
>>> (colorgrad01) for values that are on row i, from a matrix called tree1.
>>>
>>> when I use lapply:
>>>
>>> lapply(tree1$edge, create.gradient)
>>>
>>> I get the following error message:
>>>
>>> Error in FUN(X[[27L]], ...) : subscript out of bounds
>>>
>>> I'm not sure what's wrong: it could be either fact that 'colorgrad' is a
>>> character string; i.e. consisting of multiple characters and not just
>>> one,
>>> or because 'i' doesn't come back in the object 'colorgrad' that it has to
>>> return. Or it could be something else entirely...
>>>
>>> In any case, what I prefer as output is a vector with all the different
>>> 'colorgrad's it generates with each run.
>>>
>>> Thanks a lot for any help you might be able to offer!
>>> Annemarie
>>>
>>> --
>>> Annemarie Verkerk, MA
>>> Evolutionary Processes in Language and Culture (PhD student)
>>> Max Planck Institute for Psycholinguistics
>>> P.O. Box 310, 6500AH Nijmegen, The Netherlands
>>> +31 (0)24 3521 185
>>> http://www.mpi.nl/research/research-projects/evolutionary-processes
>>>
>>> ______________________________________________
>>> R-help at r-project.org mailing list
>>> https://stat.ethz.ch/mailman/listinfo/r-help
>>> PLEASE do read the posting guide
>>> http://www.R-project.org/posting-guide.html
>>> and provide commented, minimal, self-contained, reproducible code.
>>>
>>>
>>
>>
>>
>>
>
> --
> Annemarie Verkerk, MA
> Evolutionary Processes in Language and Culture (PhD student)
> Max Planck Institute for Psycholinguistics
> P.O. Box 310, 6500AH Nijmegen, The Netherlands
> +31 (0)24 3521 185
> http://www.mpi.nl/research/research-projects/evolutionary-processes
>
>



-- 
Joshua Wiley
Ph.D. Student, Health Psychology
University of California, Los Angeles
https://joshuawiley.com/



More information about the R-help mailing list