简体   繁体   中英

How to run a multi-step process in loop form in R

Dataframe:

mydata<-structure(list(ParkName = c("SEP", "CSSP", 
                    "SEP", "ONF", "SEP", 
                    "ONF", "SEP", 
                    "CSSP", "ONF", 
                    "SEP", "CSSP", 
                    "PPRSP", "PPRSP", 
                    "SEP", "ONF", 
                    "PPRSP", "ONF", 
                    "SEP", "SEP", 
                    "ONF"), 
       Year = c(2001, 2005, 1998,2011, 1991, 1991, 1991, 1991, 1991, 1992, 1992, 1992, 1992, 1992,
                                      1992, 1992, 1992, 1993, 1994, 1994), 
       LatinName = c("Mola mola", "Clarias batrachus", "Lithobates catesbeianus", "Rana catesbeiana", "Rana catesbeiana", 
                     "Rana yellowis", "Rana catesbeiana", "Solenopsis sp1","Rana catesbeiana", "Rana catesbeiana",
                     "Pratensis", "Rana catesbeiana",  "Rana catesbeiana", "sp2", "Orchidaceae",
                     "Rana catesbeiana","Formica", "Rana catesbeiana", "Rana catesbeiana", "sp2"), 
       NumTotal = c(1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1, 100, 2, 1, 2)), Names = c("ParkName", "Year", "LatinName", 
                                                                                                                  "NumTotal"),
  row.names = c(NA, -20L), class = c("tbl_df", "tbl",  "data.frame"))

This dataset represents the abundance of different species in different parks over a multitude of years. Keep in mind this is just an example dataset and the real one is rather large. What I essentially want to do with this data is to get a species X park matrix for every year that data was recorded and then use the 'vegan' package to calculate diversity indices for each park for each year.

With some help from the community I've managed to create a list of dataframes based on each year. Then I've extracted the dataframe and converted it into a Species X park matrix. I've then managed to get my diversity values of each park for that specific year. Below is the code I used:

library(vegan)
dfList <- split(mydata, mydata$Year) #obtain dataframes for every year 
x<-data.frame(dfList[1]) #select dataframe from certain year
x2<-xtabs(x$X1991.NumTotal~x$X1991.ParkName+x$X1991.LatinName, 
data=x)#convert selected dataframe into species X site matrix
exp(diversity(x2, index = "shannon")) #extract diversity values

How would I run a loop to essentially do what I did for one year and do it for all years and end up with a list of diversity values for every park for every year? The problem I have when I run loops is that this is a very unbalanced dataset so lengths don't end up matching up with one another.

A simple lapply will do what you want.

result <- lapply(dfList, function(x){
    x2 <- xtabs(NumTotal ~ ParkName + LatinName, data = x)
    exp(diversity(x2, index = "shannon")) #extract diversity values
})
result

Using base R

do.call(rbind, by(mydata, mydata$Year, function(d){
  xt <- xtabs(NumTotal ~ ParkName + LatinName, data = d)
  data.frame(year = d$Year[1], park = dimnames(xt)[[1]], div = exp(diversity(xt)))}))

#            year  park      div
# 1991.CSSP  1991  CSSP 1.000000
# 1991.ONF   1991   ONF 2.000000
# 1991.SEP   1991   SEP 1.000000
# 1992.CSSP  1992  CSSP 1.000000
# 1992.ONF   1992   ONF 1.057118
# 1992.PPRSP 1992 PPRSP 1.000000
# 1992.SEP   1992   SEP 2.000000
# 1993       1993   SEP 1.000000
# 1994.ONF   1994   ONF 1.000000
# 1994.SEP   1994   SEP 1.000000
# 1998       1998   SEP 1.000000
# 2001       2001   SEP 1.000000
# 2005       2005  CSSP 1.000000
# 2011       2011   ONF 1.000000

Using data.table

library(data.table)
mydata[ , {xt <- xtabs(NumTotal ~ ParkName + LatinName, data = .SD)
  .(park =  dimnames(xt)[[1]], div = exp(diversity(xt)))}, by = Year]

#     Year  park      div
#  1: 2001   SEP 1.000000
#  2: 2005  CSSP 1.000000
#  3: 1998   SEP 1.000000
#  4: 2011   ONF 1.000000
#  5: 1991  CSSP 1.000000
#  6: 1991   ONF 2.000000
#  7: 1991   SEP 1.000000
#  8: 1992  CSSP 1.000000
#  9: 1992   ONF 1.057118
# 10: 1992 PPRSP 1.000000
# 11: 1992   SEP 2.000000
# 12: 1993   SEP 1.000000
# 13: 1994   ONF 1.000000
# 14: 1994   SEP 1.000000

Note that by retains row order within groups, as well as order among groups.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM