Search code examples
rloopssubsetsapply

Struggling to loop within a function


I am investigating the presence of convergent evolution in a dataset containing 20 trait variables. I need to test for convergence on each trait individually, I am trying to set up a loop to do this. However, I am getting errors on my loops and I am not sure why. I can run each variable independently in the function perfectly.

I am using the package windex and am using the function test.windex. This function uses a data.frame containing information about which species are the focal ones and the traits that one wishes to test convergence on. The function also requires a phylogenetic tree for the species included in the data.frame.

To create a reproducible example I am using the sample data supplied with the package windex as my data is confidential (I have run the following and get the same errors as with my own data).

data(sample.data) #data.frame containing the focal species and variables
data(sample.tree) #phylogentic tree
head(sample.data)

  species focals      bm1        bm2      bm3 
1      s4      0 13.03895 17.2201554 11.43644 
2      s7      0 18.22705 15.2427947 22.75245  
3      s8      0 12.38588 10.5858736 13.80216     
4      s9      0 24.79114  8.1148456 23.38717       
5     s11      1 28.20126 -2.9911114 15.63215
6     s12      1 29.45775  0.9225023 12.09184                                                      
    ou1       ou2      ou3     bin                                                                           
1 13.03895 17.220155 11.43644   1                                                                    
2 18.22705 15.242795 22.75245   2                                                                    
3 12.38588 10.585874 13.80216   3                                                                    
4 24.79114  8.114846 23.38717   4                                                                    
5 21.22215 21.936316 20.30037   5                                                                    
6 21.24501 20.952824 20.88650   6

#My loop, it is the traits that I need to loop for each trait variable in the sample.data

sapply(sample.data[3:8], function(x) test.windex(sample.data,sample.tree,traits= x,
focal=sample.data[,2], reps=1000,plot=TRUE,col="light grey"))

This code generates the error: Error in .subset(x, j) : only 0's may be mixed with negative subscripts Called from: [.data.frame(dat, , traits)

I am assuming that it is some sort of an indexing problem, but I just can't seem to find a way around it. I tried this instead, but also go the same error:

traitsonly<-sample.data[3:8]
sapply(traitsonly, function(x) test.windex(sample.data,sample.tree,traits= x,
focal=sample.data[,2], reps=1000,plot=TRUE,col="light grey"))

Any help would be greatly appreciated.


Solution

  • From the help page of test.windex it accepts column number or column name.

    traits Column numbers (or names) of the traits for which you want to calculate a Wheatsheaf index.

    So either of these should work.

    library(windex)
    
    sapply(3:8, function(x) 
      test.windex(sample.data,sample.tree,traits= x,
                  focal=sample.data[,2], reps=1000,plot=TRUE,col="light grey")
    ) -> plot
    

    Or

    sapply(names(sample.data)[3:8], function(x) 
      test.windex(sample.data,sample.tree,traits= x,
                  focal=sample.data[,2], reps=1000,plot=TRUE,col="light grey")
    ) -> plot