## install the following packages #install.packages("asnipe") #install.packages("Matrix") #install.packages("survival") #install.packages("combinat") #install.packages("foreach") #install.packages("doParallel") #install.packages("matrixStats) ## A) simulate a data set with 60 animals and 600 sightings sightings <- matrix(0, nrow=600, ncol=60) # create a matrix with 600 rows and 60 columns rownames(sightings) <- c(1:600) # assign rownames 1:600 colnames(sightings) <- make.unique(rep(LETTERS, length.out = 60), sep='') # create unique labels for columns (=individual names) set.seed(003) # set seed which chooses the same set of random numbers num_sightings <- c(rpois(25,1), rpois(15,5),rpois(10,15),rpois(5,20),rpois(5,30)) # create a list with the number of times each individual has been seen (using poisson distribution with 3 different means) num_sightings <- sample(num_sightings, 60, replace=T) # randomize the order of the created number of sightings sightings[,"A"] <- rbinom(600,1,num_sightings[1]/600) # randomly fill observations for individual A with its assigned probability of being seen vector <- as.vector("A") # add invidiual A to 'vector'. An individual is added to 'vector', once its observations have been assigned. vector2 <- colnames(sightings)[colnames(sightings)!="A"] # remove individual A from vector 2, which consists of all individuals whose observations have not been assigned yet #################### for (k in 1:59) { # run the loop through 59 individuals (-1 because A's sightings have already been assigned) j <- sample(vector2, 1) # from the vector2 (individuals whose sightings have not been assigned yet), choose 1 individual at random (=j) k <- sample(vector, 1) # from vector (individuals whose sightings have been assigned), choose 1 individual at random (=k) prob1 <- rbinom(1,1,0.7)*runif(1, min=0.5) # create a probability of individual k and j being associated. rbinom produces 1 or 0 (1=associated, 0=not associated). # if they are associated, then runif creates an association strength (with a minimum of 0.5) # the next three lines concern the case where k is not present in an observation: z <- subset(sightings, sightings[,k]==0) # subset 'sightings' to only contain observations where individual k is not present z2 <- subset(z, rowSums(z)<1) # extract the number of observations that have no other individuals present (k is not present). This will be used later to reduce noise in the data set. z3 <- length(z2[,1]) # z= number of observations where no other individual is present (k is not present) for (i in 1:600) { # for all 600 observations if(sightings[i,k]==1) # if animal k was present in observation i {sightings[i,which(colnames(sightings)==j)] <- rbinom(1,1,prob1)} # then animal j will be part of that observation with probability prob1 else # if k was not present in observation i { est_num_with_k <- round(sum(sightings[,k])*prob1) # extract how many times j is expected to be seen with k (given probability prob1) est_num_without_k <- num_sightings[which(colnames(sightings)==j)] - est_num_with_k # subtract that number from the total simulated number of sightings for j seen_without_k <- sum(z[,which(colnames(sightings)==j)]) # calculate how many times j has been seen not in presence with k (from data set z) num_remaining <- est_num_without_k - seen_without_k # subtract that number from the estimated number of sightings individual j is supposed to be seen without k if(is.na(num_remaining)){num_remaining <- 0} # if it creates a 'NA' (by division through z=0), set it to 0 if(num_remaining<=0) # if individual j has reached its maximum number of sightings {sightings[i,which(colnames(sightings)==j)] <- 0} # then assign a 0 (individual j is not part of the observation) else # if individual j has sightings left { if(sum(sightings[i,])>0) # calculate the rowSums (how many individuals are already part of the observation). if there is already another individual in the observation {sightings[i,which(colnames(sightings)==j)] <- rbinom(1,1,(num_remaining/z3)*0.001)} # then multiply the probability of presence for individual j by 0.01. (this is supposed to prevent many association just above 0 and hence recudes noise) else { sightings[i,which(colnames(sightings)==j)] <- rbinom(1,1,(num_remaining/z3)*0.999) # if individual j has remaining number of sightings, multiply the presence probability times 0.99. if(is.na(sightings[i,which(colnames(sightings)==j)])) {sightings[i,which(colnames(sightings)==j)] <- 0} # if NAs are produced (by division through 0), assign a 0. } } } } sightings[is.na(sightings)] <- 0 # replace all NAs with 0 if(sum(sightings[which(colnames(sightings)==j)])==0) # if individual j per chance has not been assigned to any observations {sightings[sample(1:600,1),which(colnames(sightings)==j)] <- 1} else {sightings <- sightings} # assign 1 presence to a random observation vector <- c(vector,j) # add individual j to the vector (once its observations have been assigned). It can now serve as an associate for another individual. vector2 <- vector2[vector2!=j] # remove individual j from vector2 (as obsrvations no longer need to be assigned) } sightings <- subset(sightings, subset=rowSums(sightings)!=0) ## removes rows where no individual was sighted length(sightings[,1]) # returns number of remaining sightings after removing observations with no individuals row.names(sightings) <- seq(from=1, to=length(sightings[,1]), by=1) # rename the rows consecutively mean(rowSums(sightings)) # gives the average number of individuals per group (group size) sort(rowSums(sightings)) # gives a range of group size write.csv(sightings, "sim_data.csv") # write group by individual matrix as csv file network <- get_network(sightings, data_format = "GBI", association_index = "SRI") # create simple ratio association matrix for visualization write.csv(network, "social_network.csv") # save simple ratio association matrix as csv (to use for visualization in software 'gephi') # create a histogram with association strengths hist(get_network(sightings, data_format = "GBI", association_index = "SRI"), main="Histogram of association strengths", xlab="Association strength (Simple ratio index)") hist(network[network!=0]) ## extract how many times each individual has been seen to choose reasonable levels of sightings for error calculations and cut-off points for simulation sort(colSums(sightings)) ## the number of sightings range from 1 to 31