From d913c8b8ed1773109366efaffc58e6f0a06b0be5 Mon Sep 17 00:00:00 2001
From: Georges Kunstler <Georges.Kunstler@gmail.com>
Date: Tue, 3 Sep 2013 15:55:38 +1000
Subject: [PATCH] new version of competition function to US Spain Swiss

---
 R/FUN.TRY.R                |  22 ++++---
 R/format.function.R        |  25 ++++----
 merge.data.CANADA.R        |   3 +-
 merge.data.SPAIN.R         | 114 ++++++++++++++++++-------------------
 merge.data.SWISS.R         |  23 ++++----
 merge.data.US.R            |   9 +--
 ms/data.format.md          |   3 +
 ms/table.data.progress.ods | Bin 13580 -> 13803 bytes
 8 files changed, 105 insertions(+), 94 deletions(-)

diff --git a/R/FUN.TRY.R b/R/FUN.TRY.R
index d101206..2252d66 100644
--- a/R/FUN.TRY.R
+++ b/R/FUN.TRY.R
@@ -89,7 +89,7 @@ fun.extract.try <- function(ObservationID.t, data, Non.Trait.Data, Trait.Data) {
     names(TF.exp.data) <- "TF.exp.data"
     res.temp <- data.frame(ObservationID = ObservationID.t, AccSpeciesName = unique(data.temp$AccSpeciesName), 
         t(Vec.Non.Trait.Data), TF.exp.data, t(Vec.Trait.Data.OrigValue), t(Vec.Trait.Data.OrigUnit), 
-        t(Vec.Trait.Data.StdValue))
+        t(Vec.Trait.Data.StdValue), stringsAsFactors =FALSE)
     return(res.temp)
     
 }
@@ -227,8 +227,12 @@ fun.turn.list.in.DF <- function(sp, res.list) {
     data.genus <- t(sapply(sp, FUN = function(i, res.list) res.list[[i]]$genus, res.list = res.list))
     data.nobs <- t(sapply(sp, FUN = function(i, res.list) res.list[[i]]$nobs, res.list = res.list))
     ## create data.frame withh all observation
-    extract.species.try <- data.frame(data.mean, data.sd, data.exp, data.genus, data.nobs)
-    names(extract.species.try) <- c(paste(c("Leaf.N", "Seed.mass", "SLA", "Wood.Density"), "mean", sep = "."), paste(c("Leaf.N", "Seed.mass", "SLA", "Wood.Density"), "sd", sep = "."), paste(c("Leaf.N", "Seed.mass", "SLA", "Wood.Density"), "exp", sep = "."), paste(c("Leaf.N", "Seed.mass", "SLA", "Wood.Density"), "genus", sep = "."), paste(c("Leaf.N", "Seed.mass", "SLA", "Wood.Density"), "nobs", sep = "."))
+    extract.species.try <- data.frame(data.mean, data.sd, data.exp, data.genus, data.nobs, stringsAsFactors =FALSE)
+    names(extract.species.try) <- c(paste(c("Leaf.N", "Seed.mass", "SLA", "Wood.Density"), "mean", sep = "."),
+                                    paste(c("Leaf.N", "Seed.mass", "SLA", "Wood.Density"), "sd", sep = "."),
+                                    paste(c("Leaf.N", "Seed.mass", "SLA", "Wood.Density"), "exp", sep = "."),
+                                    paste(c("Leaf.N", "Seed.mass", "SLA", "Wood.Density"), "genus", sep = "."),
+                                    paste(c("Leaf.N", "Seed.mass", "SLA", "Wood.Density"), "nobs", sep = "."))
     return(extract.species.try)
 }
 
@@ -252,7 +256,11 @@ fun.extract.format.sp.traits.TRY <- function(sp, sp.syno.table, data) {
     
     ##### TRANSFORM LIST IN A TABLE
     extract.species.try <- fun.turn.list.in.DF(sp, res.list)
-    
+
+    ##### TODO ADD A TEST OF GOOD EXTRACTION OF TRAITS
+    test.num <- sample(1:length(sp),1)
+   if( extract.species.try[test.num,"SLA.mean"] !=  fun.species.traits(sp[test.num], species.table = sp.syno.table, 
+        traits = traits, data = data)$mean[grep("SLA",traits)]) stop('traits value not good for the  species in extraction from TRY')
     ############### add mean sd of species or genus if we want to use that
     sd.vec.sp <- readRDS(file = "./data/process/sd.vec.sp.rds")
     sd.vec.genus <- readRDS(file = "./data/process/sd.vec.genus.rds")
@@ -262,8 +270,8 @@ fun.extract.format.sp.traits.TRY <- function(sp, sp.syno.table, data) {
     genus.names <- paste(c("Leaf.N", "Seed.mass", "SLA", "Wood.Density"), 
         "genus", sep = ".")
     ### add columns
-    extract.species.try.2 <- data.frame(extract.species.try, extract.species.try[, 
-        sd.names])
+    extract.species.try.2 <- data.frame(extract.species.try,
+                                        extract.species.try[,sd.names], stringsAsFactors =FALSE)
     
     ## update value
     sd.names.1 <- paste(sd.names, 1, sep = ".")
@@ -272,7 +280,7 @@ fun.extract.format.sp.traits.TRY <- function(sp, sp.syno.table, data) {
         extract.species.try.2[[sd.names.1[i]]][extract.species.try.2[[genus.names[i]]]] <- sd.vec.genus[i]
     }
     data.frame.TRY <- data.frame(sp = sp, Latin_name = sp.syno.table[["Latin_name_syn"]], 
-        extract.species.try.2)
+        extract.species.try.2, stringsAsFactors =FALSE)
     if (sum(!data.frame.TRY[["sp"]] == sp) > 0) 
         stop("Wrong order of species code")
     return(data.frame.TRY)
diff --git a/R/format.function.R b/R/format.function.R
index 0526a8b..6b7fa86 100644
--- a/R/format.function.R
+++ b/R/format.function.R
@@ -62,6 +62,7 @@ BA.fun <- function(diam,weights){
 ##' @return data frame with obs.id and one column per species with basal area of the species (without the target tree)
 ##' @author Kunstler
 BA.SP.FUN <-  function(obs.id,diam,sp,id.plot,weights,weight.full.plot){
+print(length(obs.id))
 require(data.table)
 id.plot <- as.character(id.plot)
 obs.id <-  as.character(obs.id)
@@ -194,6 +195,7 @@ return(BA.SP.FUN.XY(obs.id[census==census.id],xy.table[census==census.id,],diam[
 ### wrapping function to run BA.SP.FUN.XY per census
 BA.SP.FUN.XY.census <-  function(census,obs.id,xy.table,diam,sp,Rlim,parallel=FALSE,rpuDist=FALSE){
 unique.census <- unique(census)
+print(unique.census)
 res.list <- lapply(unique.census,FUN=BA.SP.FUN.XY.l,obs.id,xy.table,diam,sp,Rlim,parallel,rpuDist)
 res.mat <- rbind.fill(res.list )
 res.mat <- res.mat[match(obs.id,rownames(res.mat)),]
@@ -264,6 +266,7 @@ if(is.null(data.tot[['weights']])) stop("Please create a weights vector, even if
 require(data.table)
 data.tot <-  data.table(data.tot)
 data <- data.tot[ecocode==ecoregion,]
+print(dim(data))
 rm(data.tot)
 data.BA.SP <- BA.SP.FUN.census(census=data[['census']],
                                obs.id=as.vector(data[['obs.id']]),
@@ -296,17 +299,17 @@ setkeyv(data,"obs.id")
 if(sum(!data.BA.sp[["obs.id"]] == data[["obs.id"]]) >0) stop("competition index not in the same order than data")
 #####
 ## ADD TRY DATA OR TRAITS IF NEEDED
-if(!is.na(data.TRY)){
-sp.extract <- species.lookup[species.lookup[["sp"]] %in% unique(data[["sp"]]),]
-data.traits <- fun.extract.format.sp.traits.TRY(sp=sp.extract[["sp"]],sp.syno.table=sp.extract,data.TRY)
-### TO DO ADD OPTION TO INCLUE OTHER DATA on MAX HEIGHT
-## save everything as a list
-print(dim(data.traits))
-list.temp <- list(data.tree=data,data.BA.SP=data.BA.sp,data.traits=data.traits)
-save(list.temp,file=paste("./data/process/list",name.country,ecoregion,"Rdata",sep="."))
+if(is.data.frame(data.TRY)){
+   sp.extract <- species.lookup[species.lookup[["sp"]] %in% unique(data[["sp"]]),]
+   data.traits <- fun.extract.format.sp.traits.TRY(sp=sp.extract[["sp"]],sp.syno.table=sp.extract,data.TRY)
+   ### TO DO ADD OPTION TO INCLUE OTHER DATA on MAX HEIGHT
+   ## save everything as a list
+   print(dim(data.traits))
+   list.temp <- list(data.tree=data,data.BA.SP=data.BA.sp,data.traits=data.traits)
+   save(list.temp,file=paste("./data/process/list",name.country,ecoregion,"Rdata",sep="."))
 }else{
-list.temp <- list(data.tree=data,data.BA.SP=data.BA.sp,data.traits=NA)
-saveRDS(list.temp,file=paste("./data/process/list",name.country,ecoregion,"Rdata",sep="."))
+   list.temp <- list(data.tree=data,data.BA.SP=data.BA.sp,data.traits=NA)
+   saveRDS(list.temp,file=paste("./data/process/list",name.country,ecoregion,"Rdata",sep="."))
 }
 }    
 
@@ -336,7 +339,7 @@ if(sum(!colnames(BA.SP.temp)==as.character((levels(data.tree.s[['sp']]))))>0) st
 
 ### compute sum per row
 BATOT <- apply(BA.SP.temp,MARGIN=1,FUN=sum)
-data.res <- data.frame(obs.id=data.tree.s[['obs.id']],BA.SP.temp,BATOT=BATOT)
+data.res <- data.frame(obs.id=data.tree.s[['obs.id']],BA.SP.temp,BATOT=BATOT, stringsAsFactors =FALSE)
 return(data.res)
 }
 
diff --git a/merge.data.CANADA.R b/merge.data.CANADA.R
index 4abfd33..8711afb 100644
--- a/merge.data.CANADA.R
+++ b/merge.data.CANADA.R
@@ -1,11 +1,10 @@
 ### MERGE canada DATA Edited by FH
 rm(list = ls())
 source("./R/format.function.R")
+source("./R/FUN.TRY.R")
 library(reshape)
 
 ######################### READ DATA read individuals tree data data.canada <-
-######################### read.csv('./data/raw/DataCanada/Canada_Data2George_20130816.csv',header=TRUE,stringsAsFactors
-######################### =FALSE)
 data.canada <- read.csv("./data/raw/DataCanada/Canada_Data2George_20130818.csv", 
     header = TRUE, stringsAsFactors = FALSE)
 data.canada <- data.canada[which(!is.na(data.canada$Species)), ]
diff --git a/merge.data.SPAIN.R b/merge.data.SPAIN.R
index 7da9b81..15eb6a9 100644
--- a/merge.data.SPAIN.R
+++ b/merge.data.SPAIN.R
@@ -1,6 +1,7 @@
 ### MERGE spain DATA Edited by FH
 rm(list = ls())
 source("./R/format.function.R")
+source("./R/FUN.TRY.R")
 library(reshape)
 
 ######################### READ DATA read individuals tree data data.spain <-
@@ -18,22 +19,9 @@ res.quant.boot <- t(sapply(levels(factor(data.spain[["SP_code"]])), FUN = f.quan
 
 ## create data base
 data.max.height <- data.frame(code = rownames(res.quant.boot), Max.height.mean = res.quant.boot[, 
-    1], Max.height.sd = res.quant.boot[, 2], Max.height.nobs = res.quant.boot[, 3])
+    1], Max.height.sd = res.quant.boot[, 2], Max.height.nobs = res.quant.boot[, 3], stringsAsFactors =FALSE)
 rm(res.quant.boot)
 write.csv(data.max.height, file = "./data/process/data.max.height.spain.csv")  # I was planning to save processed data in that folder
-# ## merge TRY with max height merge.TRY <-
-# merge(merge.TRY,data.max.height,by='code') rm(data.max.height) ## use mean sd
-# of max tree height over all species merge.TRY$Max.height.sd.1 <-
-# rep(mean(merge.TRY[['Max.height.sd']],na.rm=TRUE),length=nrow(merge.TRY)) ###
-# keep only variables needed in traits data names.traits.data <-
-# c('code','Latin_name','Leaf.N.mean','Seed.mass.mean','SLA.mean','Wood.Density.mean',
-# 'Leaf.Lifespan.mean','Max.height.mean','Leaf.N.sd.1','Seed.mass.sd.1','SLA.sd.1',
-# 'Wood.Density.sd.1', 'Leaf.Lifespan.sd.1','Max.height.sd.1') data.traits <-
-# merge.TRY[,names.traits.data] names(data.traits) <-
-# c('sp','Latin_name','Leaf.N.mean','Seed.mass.mean','SLA.mean','Wood.Density.mean',
-# 'Leaf.Lifespan.mean','Max.height.mean','Leaf.N.sd','Seed.mass.sd','SLA.sd',
-# 'Wood.Density.sd', 'Leaf.Lifespan.sd','Max.height.sd') ## rename to have
-# standard variables name rm(merge.TRY,names.traits.data)
 
 ################################################################ FORMAT INDIVIDUAL TREE DATA
 
@@ -42,11 +30,14 @@ data.spain$G <- data.spain[["adbh"]]  ## diameter growth in mm per year
 data.spain$year <- data.spain[["years"]]  ## number of year between measurement - MISSING
 data.spain$D <- data.spain[["dbh1"]]/10  ## diameter in mm convert to cm
 data.spain$dead <- as.numeric(data.spain[["Life_status"]] == "dead")  ## dummy variable for dead tree 0 alive 1 dead - MIGHT WANT TO CHANGE THIS TO BE BASED ON MORTALITY_CUT
-data.spain$sp <- as.character(data.spain[["SP_code"]])  ## species code
+data.spain$sp <- paste("sp",(data.spain[["SP_code"]]) ,sep=".") ## species code
+data.spain$sp.name <-  data.spain[["SP_name"]]
 data.spain$plot <- (data.spain[["Plot_ID_SFI"]])  ## plot code
 data.spain$htot <- data.spain[["ht1"]]  ## height of tree in m
 data.spain$tree.id <- data.spain$Tree_ID_SFI  ## tree unique id
-
+data.spain$obs.id <- as.character(1:nrow(data.spain)) ## obs uniquue id
+data.spain$census <- rep(1,nrow(data.spain)) ## only one census in spain
+data.spain$weights <- as.vector(1/(pi * (data.spain[["R1"]])^2)) ## weights in 1/m^2
 #### change coordinates system of x y to be in lat long WGS84
 library(sp)
 library(dismo)
@@ -80,14 +71,14 @@ table(data.spain$eco_code)
 ## There's an eco-region with no code, and one with < 1000 sites The former we
 ## could drop as they were on the border of Spain
 
+### PLOT ECOREGION
 library(RColorBrewer)
 mycols <- brewer.pal(10, "Set3")
-
 ecoreg <- unclass(data.spain$eco_code)
 
+pdf("./figs/ecoregion.spain.pdf")
 plot(data.spain[["CX"]][order(ecoreg)], data.spain[["CY"]][order(ecoreg)], pty = ".", 
     cex = 0.2, col = rep(mycols, as.vector(table(ecoreg))))
-
 legend("topleft", col = mycols, legend = levels(data.spain$eco_code), pch = rep(19, 
     length(levels(ecoreg))), cex = 2)
 points(data.spain[["CX"]][ecoreg == 9], data.spain[["CY"]][ecoreg == 9], pty = ".", 
@@ -97,56 +88,65 @@ points(data.spain[["CX"]][ecoreg == 1], data.spain[["CY"]][ecoreg == 1], pty = "
     cex = 0.5, col = "black")
 ## Highlight the 'rare' ecoregions PA1219 looks to be similar to PA1209, merge
 ## them together
+dev.off()
+
+## merge
 data.spain$eco_codemerged <- combine_factor(data.spain$eco_code, c(1:8, 6, 9))
 data.spain <- data.spain[-which(data.spain$eco_codemerged == ""), ]
 
-###################### PERCENT DEAD variable percent dead/cannot do with since dead variable is
-###################### missing compute numer of dead per plot to remove plot with disturbance
+#####
+## PLOT of  MERGED ECOREGION
+## mycols <- brewer.pal(9, "Set3")
+## plot(data.spain[["CX"]][order(data.spain$eco_codemerged)], data.spain[["CY"]][order(data.spain$eco_codemerged)], pty = ".", 
+##     cex = 0.2, col = rep(mycols, as.vector(table(data.spain$eco_codemerged))))
+## legend("topleft", col = mycols, legend = levels(data.spain$eco_codemerged), pch = rep(19, 
+##     length(levels(data.spain$eco_codemerged))), cex = 2)
+
+###################### PERCENT DEAD 
+###################### compute numer of dead per plot to remove plot with disturbance
 perc.dead <- tapply(data.spain[["dead"]], INDEX = data.spain[["plot"]], FUN = function.perc.dead)
 table(data.spain$dead)
 ## VARIABLE TO SELECT PLOT WITH NOT BIG DISTURBANCE KEEP OFTHER VARIABLES IF
 ## AVAILABLE (disturbance record)
-data.spain <- merge(data.spain, data.frame(plot = as.numeric(names(perc.dead)), perc.dead = perc.dead), 
-    sort = FALSE, by = "plot")
+data.spain <- merge(data.spain, data.frame(plot = as.numeric(names(perc.dead)), perc.dead = perc.dead, stringsAsFactors =FALSE), 
+                    sort = FALSE, by = "plot")
 
 ########################################################### PLOT SELECTION FOR THE ANALYSIS Remove data with mortality == 1 or 2
-table(data.spain$Mortality_Cut)
-data.spain <- subset(data.spain, subset = (data.spain[["Mortality_Cut"]] == 0 | data.spain[["Mortality_Cut"]] == 
-    ""))
+data.spain <- subset(data.spain,
+                     subset = (data.spain[["Mortality_Cut"]] == 0 |
+                               data.spain[["Mortality_Cut"]] ==  ""))
 
 colnames(data.spain)[colnames(data.spain) %in% c("mat", "pp", "PET")] <- c("MAT", 
     "PP", "PET")
 colnames(data.spain)[names(data.spain) == "eco_codemerged"] <- c("ecocode")
 vec.abio.var.names <- c("MAT", "PP", "PET")
-vec.basic.var <- c("tree.id", "sp", "sp.name", "plot", "ecocode", "D", "G", "dead", 
-    "year", "htot", "Lon", "Lat", "perc.dead")
-data.tree <- subset(data.spain, select = c(vec.basic.var, vec.abio.var.names))
-save(data.spain, file = "./data/process/datspain.RData")
-
-############################################## COMPUTE MATRIX OF COMPETITION INDEX WITH SUM OF BA PER SPECIES IN EACH PLOT in
-############################################## m^2/ha without the target species
-data.BA.SP <- BA.SP.FUN(id.tree = as.vector(data.spain[["tree.id"]]), diam = as.vector(data.spain[["D"]]), 
-    sp = as.vector(data.spain[["sp"]]), id.plot = as.vector(data.spain[["plot"]]), 
-    weights = as.vector(1/(pi * (data.spain[["R1"]])^2)), weight.full.plot = 1/(pi * 
-        (25)^2))
-
-## change NA and <0 data for 0
-data.BA.SP[which(is.na(data.BA.SP), arr.ind = TRUE)] <- 0
-data.BA.SP[, -1][which(data.BA.SP[, -1] < 0, arr.ind = TRUE)] <- 0
-
-### CHECK IF sp and sp name for column are the same
-if (sum(!(names(data.BA.SP)[-1] %in% unique(data.spain[["sp"]]))) > 0) stop("competition index sp name not the same as in data.tree")
-
-#### compute BA tot for all competitors
-BATOT.COMPET <- apply(data.BA.SP[, -1], MARGIN = 1, FUN = sum, na.rm = TRUE)
-data.BA.SP$BATOT.COMPET <- BATOT.COMPET
-### create data frame
-names(data.BA.SP) <- c("tree.id", names(data.BA.SP)[-1])
-data.BA.sp <- merge(data.frame(tree.id = dataIFN.spain[["tree.id"]], ecocode = dataIFN.spain[["ecocode"]]), 
-    data.BA.SP, by = "tree.id", sort = FALSE)
-## test
-if (sum(!data.BA.sp[["tree.id"]] == data.tree[["tree.id"]]) > 0) stop("competition index not in the same order than data.tree")
-
-## save everything as a list
-list.spain <- list(data.tree = data.tree, data.BA.SP = data.BA.sp, data.traits = data.traits)
-save(list.spain, file = "./data/process/list.spain.Rdata") 
+vec.basic.var <- c("tree.id","obs.id", "sp", "sp.name", "plot", "ecocode", "D", "G", "dead", 
+    "year", "htot", "Lon", "Lat", "perc.dead","census","weights")
+data.spain <- subset(data.spain, select = c(vec.basic.var, vec.abio.var.names))
+
+
+
+
+############################################## 
+############################################## 
+#################### GENERATE ONE OBJECT PER ECOREGION
+
+# vector of ecoregion name
+ecoregion.unique <- unique(data.spain[["ecocode"]])
+sum(data.spain[["ecocode"]] == ecoregion.unique[1])
+
+### read TRY data
+TRY.DATA.FORMATED <- readRDS("./data/process/TRY.DATA.FORMATED.rds")
+
+## create lookup table for spain
+species.lookup <- data.frame(sp=data.spain[!duplicated(data.spain[["sp"]]),"sp"],
+                             Latin_name=data.spain[!duplicated(data.spain[["sp"]]),"sp.name"],
+                             Latin_name_syn=data.spain[!duplicated(data.spain[["sp"]]),"sp.name"],
+                             stringsAsFactors =FALSE)
+
+
+#### lapply function to generate data per ecoregion
+system.time(lapply(ecoregion.unique[1:2], FUN = fun.data.per.ecoregion, data.tot = data.spain, 
+    plot.name = "plot", weight.full.plot = NA, name.country = "Spain", data.TRY = TRY.DATA.FORMATED, 
+    species.lookup = species.lookup))
+
diff --git a/merge.data.SWISS.R b/merge.data.SWISS.R
index 2efc7a5..58ed741 100644
--- a/merge.data.SWISS.R
+++ b/merge.data.SWISS.R
@@ -59,9 +59,9 @@ res.quant.boot <- t(sapply(levels(factor(data.swiss[["spcode"]])), FUN = f.quant
 
 ## create data base
 data.max.height <- data.frame(code = rownames(res.quant.boot), Max.height.mean = res.quant.boot[, 
-    1], Max.height.sd = res.quant.boot[, 2], Max.height.nobs = res.quant.boot[, 3])
+    1], Max.height.sd = res.quant.boot[, 2], Max.height.nobs = res.quant.boot[, 3], stringsAsFactors =FALSE)
 rm(res.quant.boot)
-# write.csv(data.max.height,file='./data/process/data.max.height.swiss.csv')
+write.csv(data.max.height,file='./data/process/data.max.height.swiss.csv')
 
 ########################################## FORMAT INDIVIDUAL TREE DATA change unit and names of variables to be the same
 ########################################## in all data for the tree
@@ -83,7 +83,7 @@ data.swiss$ecocode <- rep("A", nrow(data.swiss))
 perc.dead <- tapply(data.swiss[["dead"]], INDEX = data.swiss[["plot"]], FUN = function.perc.dead)
 # ## VARIABLE TO SELECT PLOT WITH NOT BIG DISTURBANCE KEEP OTHER VARIABLES IF
 # AVAILABLE (disturbance record)
-data.swiss <- merge(data.swiss, data.frame(plot = names(perc.dead), perc.dead = perc.dead), 
+data.swiss <- merge(data.swiss, data.frame(plot = names(perc.dead), perc.dead = perc.dead, stringsAsFactors =FALSE), 
     by = "plot", sort = FALSE)
 
 ########################################################### PLOT SELECTION FOR THE ANALYSIS Remove data with dead == 1
@@ -94,15 +94,12 @@ data.climate <- data.climate[, c(1, 7, 15:19)]
 data.climate$MAP <- apply(data.climate[, 4:7], 1, sum)
 
 data.swiss <- merge(data.swiss, data.frame(siteid = data.climate$CLNR, swb = data.climate$swb_100, 
-    MAT = data.climate$tave_68, MAP = data.climate$MAP), sort = F, all.x = T)
+    MAT = data.climate$tave_68, MAP = data.climate$MAP, stringsAsFactors =FALSE), sort = F, all.x = T)
 rm(data.climate)
 
-############################################## COMPUTE MATRIX OF COMPETITION INDEX WITH SUM OF BA PER SPECIES IN EACH PLOT in
-############################################## m^2/ha without the target species
-data.BA.SP <- BA.SP.FUN.census(census=data.swiss[["census"]],obs.id=data.swiss[["obs.id"]],diam=data.swiss[["D"]],sp=data.swiss[["sp"]],id.plot=data.swiss[["plot"]],weights=data.swiss[["weights"]],weight.full.plot=NA)
-
-## check if good order
- sum(! (data.BA.SP[,"obs.id"]) == data.swiss[["obs.id"]])
+############################################## 
+############################################## 
+#################### GENERATE ONE OBJECT PER ECOREGION
 
 # vector of ecoregion name
 ecoregion.unique <- unique(data.swiss[["ecocode"]])
@@ -114,11 +111,11 @@ TRY.DATA.FORMATED <- readRDS("./data/process/TRY.DATA.FORMATED.rds")
 ## create lookup table for swiss
 species.lookup <- data.frame(sp=data.swiss[!duplicated(data.swiss[["sp"]]),"sp"],
            Latin_name=data.swiss[!duplicated(data.swiss[["sp"]]),"sp.name"],
-           Latin_name_syn=data.swiss[!duplicated(data.swiss[["sp"]]),"sp.name"])
+           Latin_name_syn=data.swiss[!duplicated(data.swiss[["sp"]]),"sp.name"], stringsAsFactors =FALSE)
 
 
-#### lapply function
-(lapply(ecoregion.unique, FUN = fun.data.per.ecoregion, data.tot = data.swiss, 
+#### lapply function to generate data for each ecoregion
+system.time(lapply(ecoregion.unique, FUN = fun.data.per.ecoregion, data.tot = data.swiss, 
     plot.name = "plot", weight.full.plot = NA, name.country = "Swiss", data.TRY = TRY.DATA.FORMATED, 
     species.lookup = species.lookup))
 
diff --git a/merge.data.US.R b/merge.data.US.R
index 275c7c1..399f931 100644
--- a/merge.data.US.R
+++ b/merge.data.US.R
@@ -41,7 +41,8 @@ data.us$htot <- rep(NA, length(data.us[["Species"]]))  ## height of tree in m -
 data.us$tree.id <- as.character(data.us$TreeID)
 ## tree unique id
 data.us$sp.name <- NA
-
+## census is missing use as only one census and check with mark
+data.us$census <- rep(1,nrow(data.us))
 ### add plot weights for computation of competition index (in 1/m^2)
 data.us$weights <- 1/(10000 * data.us[["PlotSize"]])
 
@@ -68,7 +69,7 @@ for (i in 1:length(sel.small.div)) {
 perc.dead <- tapply(data.us[["dead"]], INDEX = data.us[["plot"]], FUN = function.perc.dead)
 # ## VARIABLE TO SELECT PLOT WITH NOT BIG DISTURBANCE KEEP OFTHER VARIABLES IF
 # AVAILABLE (disturbance record)
-data.us <- merge(data.us, data.frame(plot = names(perc.dead), perc.dead = perc.dead), 
+data.us <- merge(data.us, data.frame(plot = names(perc.dead), perc.dead = perc.dead, stringsAsFactors = FALSE), 
     by = "plot", sort = FALSE)
 
 
@@ -86,7 +87,7 @@ data.us[["sp"]] <- paste("sp", data.us[["sp"]], sep = ".")
 ## variables to keep
 vec.abio.var.names <- c("MAT", "MAP")
 vec.basic.var <- c("tree.id", "sp", "plot", "subplot", "ecocode", "D", "G", "dead", 
-    "year", "htot", "Lon", "Lat", "perc.dead", "weights")
+    "year", "htot", "Lon", "Lat", "perc.dead", "weights","census")
 data.tree <- subset(data.us, select = c(vec.basic.var, vec.abio.var.names))
 rm(data.us)
 ## creat row unique id
@@ -103,6 +104,6 @@ ecoregion.unique <- unique(data.tree[["ecocode"]])
 
 
 #### lapply function
-system.time(lapply(ecoregion.unique, FUN = fun.data.per.ecoregion, data.tot = data.tree, 
+system.time(lapply(ecoregion.unique[3], FUN = fun.data.per.ecoregion, data.tot = data.tree, 
     plot.name = "subplot", weight.full.plot = NA, name.country = "US", data.TRY = TRY.DATA.FORMATED, 
     species.lookup = species.clean)) 
diff --git a/ms/data.format.md b/ms/data.format.md
index 8f42907..1dd2df4 100644
--- a/ms/data.format.md
+++ b/ms/data.format.md
@@ -14,6 +14,7 @@ For the analysis we need for each ecoregion country (or big tropical plot) a lis
 
 * First element is a  data.frame for individual tree data with columns
 
+	- $obs.id4 a unique identifier of observqtion (if multiple observation for a same tree)
     - $tree.id$ a unique identifier of each tree
     - $sp$ the species code
     - $plot$ the plot code
@@ -22,10 +23,12 @@ For the analysis we need for each ecoregion country (or big tropical plot) a lis
     - $G$ the diameter growth rate in mm / yr.
     - $dead$ a dummy variable 0 alive 1 dead
     - $year$ the number of year for the growth measurement
+	- $census$ the name of the year of the census 1
     - $htot$ the height of the individual (m) for the data base for which it is availble to compute max height per species
     - $Lon$ Longitude of the plot in WGS84
     - $Lat$ Latitude of teh plots in WGS84
     - $perc.dead$ the percentage of dead computed on each plot to exlude plot with perturbation (equal 1 for plot with known perturbation)
+	- $weights$ the weigths of teh tree to have an estimation of basal area per m^2 (so 1/(m^2))
 	- then the potential  abiotic variables that we can use in the analysis
 
 * Second element is a data.frame competition index with columns
diff --git a/ms/table.data.progress.ods b/ms/table.data.progress.ods
index 45ad7a04fb61990b230d2d804cdfdd98e5175b1e..066e23e01c71741e74cd25e4e18686f32392640e 100644
GIT binary patch
delta 11558
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
G@Bagq_I{uM

delta 11316
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

-- 
GitLab