Rarefaction in specaccum producing errors for some data but not others of the same layout - r

I am trying to produce rarefied species accumulation curves for two different habitat types using the rarefaction method in specaccum function of the vegan package using the code:
spa <- specaccum(Example, method = "rarefaction")
The function works for one data set but not the other where it produces this error:
Error in rarefy(t(freq), ind[i], se = TRUE) :
function accepts only integers (counts)
However, the data is laid out exactly the same as the other data set and when I investigate the data frame it says that all the data for the species is in integer form.
Here is a much smaller section of the data frame:
Site AA AB AC AD AE AF AG AH AI AJ AK AL
1.1 0 0 0 0 1 0 0 2 0 0 0 0
1.2 1 0 0 0 0 0 0 0 0 0 0 0
1.3 0 0 1 0 0 0 0 0 0 0 0 0
2.1 1 0 0 0 1 0 0 0 0 0 0 0
2.2 0 1 0 0 0 0 0 0 0 0 0 0
2.3 0 0 0 0 0 0 0 1 0 0 1 1
3.2 0 2 1 0 1 0 0 0 0 0 0 0
3.3 0 0 0 0 2 0 0 3 0 0 0 0
4.1 0 0 0 0 0 0 1 1 0 0 0 0
4.2 0 0 0 0 0 0 0 0 0 0 0 0
4.3 0 0 0 0 1 0 0 1 0 0 0 0
5.1 0 1 0 0 0 1 0 3 0 0 0 0
5.2 0 0 1 0 2 0 0 1 0 0 0 0
5.3 0 0 0 1 3 2 0 4 0 0 0 0
6.1 0 0 0 0 0 0 0 0 0 0 0 0
6.2 0 2 2 0 0 2 0 0 0 0 0 0
6.3 0 0 0 0 0 0 0 0 0 0 0 0
Sites being sampling points within the habitat site, letters denoting species. I am unsure as to why it is working for one set of data but not the other when they are both laid out like this. Can someone help me understand?
Thanks

Related

Standard deviation error for EcoTest.sample

I am using EcoTest.sample to compare rarefaction curves for 19 vegetation plots on two soil types (alluvial and canyon). The code below produces the following
warning (more than 50 times): "In cor(x > 0) : the standard deviation is zero".
The test still produces all the expected output. Should I be concerned about the warnings? Is it a result of my relatively small sample size?
rawdata<-read.table(text="Plot SiteType sp1 sp2 sp3 sp4 sp5 sp6 sp7 sp8 sp9 sp10 sp11 sp12 sp13 sp14 sp15 sp16 sp17 sp18 sp19 sp20 sp21 sp22 sp23 sp24 sp25 sp26 sp27 sp28 sp29 sp30 sp31 sp32 sp33 sp34 sp35
2 canyon 1 0 1 0 1 1 0 1 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0
3 alluvial 1 0 0 0 0 1 1 1 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0
5 alluvial 1 0 0 0 0 0 0 1 1 0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0
6 alluvial 1 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 1 0 1 1 0 0 0 1 0 0 0 0 0 0 1 0 0
7 alluvial 1 0 0 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0
8 alluvial 1 0 1 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 1 0 1 0 0
10 alluvial 1 0 1 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 1 0 1 1 1 0 0
11 canyon 1 1 0 0 0 1 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 0
12 canyon 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
13 canyon 1 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 1 0 0 0 0 0
14 canyon 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
15 canyon 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 1 0 0 0 0 0
16 canyon 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
17 canyon 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0
18 canyon 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0
19 canyon 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0
20 canyon 1 0 0 0 0 1 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 1
22 alluvial 1 0 0 0 0 1 0 0 0 1 0 0 1 0 1 0 0 0 0 0 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0
23 alluvial 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 0 0 1 0 0 0 0 0 1 0 0 0 0
", header=T)
data<-rawdata[,-1]
rownames(data)<-rawdata[,1]
test.data<-EcoTest.sample(data[,-1], by=data$SiteType, MARGIN=1, trace=F)
EDIT: Perhaps you need to set the nature of the index using q. For instance if I use q=2 the inverse Simpson index, I cannot reproduce your error. As it stands you're using q=0, the species richness. Perhaps there's nothing to do rather than using a different index. I'm not aware of the factors affecting index choice. I've read a thing or two here: http://www.tiem.utk.edu/~gross/bioed/bealsmodules/shannonDI.html and found this paper that I didn't go into much detail: https://dx.doi.org/10.1002%2Fece3.1155
Using Simpson's index: No warnings.
test.data<-EcoTest.sample(data[,-1], by=data$SiteType, MARGIN=1, trace=F,q=2)
Sample-based method
P(Obs <= null) = 0.205
As stated in this answer on SE, a standard deviation of zero will have an impact on the nature of the distribution. Therefore, any tests you perform that may have depended on a normal distribution will likely be erroneous. The p-values obtained say by a t-test may therefore be "insignificant."
When standard deviation is zero, your Gaussian (normal) PDF turns into Dirac delta function. You can't simply plug zero standard deviation into the conventional expression. For instance, if the PDF is plugged into some kind of numerical integration, this won't work. (Aksakal on SE)
https://stats.stackexchange.com/questions/233834/what-is-the-normal-distribution-when-standard-deviation-is-zero

How do I change color of interactions based on interaction value using an ifelse() statement in an plotweb bipartite?

Hi I am having trouble trying to get ifelse statements to work in a plotweb fuction (from bipartite) to color interaction based on the total quantity of interaction of each cell in the matrix. I had the same problem with the high bar colors, but since there were only a few values and one vector, it was easy to manually code.
Here is the code I am using, I want to color interactions greater than 15 as dark turquoise and keep the rest as default grey (grey80).
I have tried many different statements but I cant seem how to figure out what to put in the [,] to signify for the function to go through every individual cell and apply the statement instead of summing them, elem,elem also doesn't seem to work. Attached is a picture of the function's output currently
plotweb(LadyNet,
abuns.type='additional',
arrow="up.center",
text.rot=90,
col.low=c("olivedrab3"),
col.interaction =(ifelse(LadyNet[,] < 15,'grey80','darkturquoise')),
col.high = c("grey10","#FF0000","grey10","#FF0000","grey10","#FF0000","grey10","grey10","grey10"),
high.lab.dis = 0,
ybig=1.2,
y.width.high = .06,
high.spacing = 0.011,
y.lim = c(-1,2))
COCCAL COCSEP CYCPOL CYCSAN EXOFAS HIPCON PSYVIG SCY1 SCYMAR
Acmispon glaber 0 1 0 1 0 0 0 0 0
Ambrosia psilostachya 1 36 0 24 0 6 0 0 0
Artemisia douglasiana 0 0 0 1 0 1 0 0 0
Asclepias fascicularis 0 5 0 4 0 2 0 0 0
Avena fatua 6 10 0 0 0 4 0 0 0
Baccharis pilularis 9 76 0 38 0 27 0 1 0
Baccharis salicifolia 0 2 0 0 0 0 0 0 0
Bromus diandrus 1 8 0 0 0 4 0 0 0
Capsicum annuum 0 0 0 0 0 0 0 0 1
Chenopodium murale 0 1 0 0 0 0 0 0 0
Croton californicus 3 20 0 13 0 54 4 0 0
DEAD WOOD 0 1 0 0 0 0 0 0 0
Distichilis spicata 0 1 0 0 0 0 0 0 0
Echium candicans 0 1 0 3 0 0 0 0 0
Eleocharis acicularis 0 1 0 0 0 0 0 0 0
Encelia californica 1 1 0 3 0 2 0 0 0
Epilobium canum 0 0 0 1 0 0 0 0 0
Erigeron bonariensis 0 4 0 0 0 0 0 0 0
Erigeron canadensis 0 17 0 10 0 2 0 0 0
Erigeron sumatrensis 0 13 0 0 0 1 0 0 0
Eriophyllum confertiflorum 1 10 0 0 0 1 0 0 0
Fence 0 0 0 1 0 0 0 0 0
Festuca perennis 0 1 0 0 0 2 0 0 0
Gambelium speciosa 0 0 0 0 0 1 0 0 0
Geranium dissectum 0 0 0 3 0 0 0 0 0
GROUND 0 1 0 1 0 0 0 0 0
Helminthotheca echioides 0 1 2 17 0 1 0 0 0
Heterotheca grandiflora 2 92 0 12 0 7 1 0 0
Hirschfieldia incana 0 3 0 0 0 1 0 0 0
Juncus patens 0 1 0 0 0 0 0 0 0
Laennecia coulteri 1 65 0 2 0 3 0 0 0
Lobularia maritima 1 1 0 0 0 0 0 0 0
Morus sp. 0 0 0 1 0 0 0 0 0
NoPicture 4 3 0 3 3 2 3 0 0
Oxalis pes-caprae 4 6 0 0 0 2 0 0 0
Pennisetum clandestinum 1 5 0 0 0 0 0 0 0
Polygonum arenastrum 0 1 0 0 0 0 0 0 0
Raphanus sativus 0 1 0 0 0 0 0 0 0
ROCK 0 0 0 1 0 0 0 0 0
Rumex crispus 0 1 0 0 0 0 0 0 0
Rumex salicifolius 0 0 0 3 0 0 0 0 0
Salsola tragus 1 6 0 1 0 1 0 0 0
Salvia leucophylla 0 1 0 0 0 1 0 0 0
Schenoplectus americanus 0 1 0 0 0 0 0 0 0
Solanum nigrum 0 0 0 0 0 1 0 0 0
Sonchus arvensis 0 1 0 0 0 0 0 0 0
Spinacia oleracea 0 0 0 0 0 0 1 0 0
Stipa pulchra 0 1 0 0 0 0 0 0 0
Symphiotrichum subulatum 0 88 0 7 0 3 0 0 0
THATCH 1 3 0 0 0 4 0 0 0
Verbena lasiostachys 1 9 0 0 0 2 0 0 0
For Reference, I have gotten the ifelse statement to function properly in the plotweb function when there was only one species in the lower level attached is an example along with the code:
plotweb(rnet,
abuns.type='additional',
arrow="down.center",
text.rot=90,
col.low=c("olivedrab3"),
col.interaction =(ifelse(rnet[1,] < 12,'grey80','darkturquoise')),
col.high = (ifelse(rnet[1,] < 12,'grey10','darkturquoise')),
high.lab.dis = 0,
ybig=1.2,
y.width.high = .06,
high.spacing = 0.011)
One thing to note is that the col.interaction color matrix should be transposed.
Here is an example that I trust you will find useful:
library(bipartite)
library(grDevices)
plotweb(df,
abuns.type='additional',
arrow="up.center",
text.rot=90,
col.low=c("olivedrab3"),
col.interaction = t(ifelse(df[,] < 15,
adjustcolor('grey80', alpha.f = 0.5), #add alpha to colors
adjustcolor('darkturquoise', alpha.f = 0.5))),
col.high = c("grey10",
"#FF0000",
"grey10",
"#FF0000",
"grey10",
"#FF0000",
"grey10",
"grey10",
"grey10"),
bor.col.interaction = NA, #remove the black border color
high.lab.dis = 0,
ybig=1.2,
y.width.high = .06,
high.spacing = 0.011,
y.lim = c(-1,2))

Filling a table with additional columns if they don't exist

I've the following difficult problem. Here short example of my data. Assume that I've two data sets (my real example has something about 20). The data frames result as a list computed by a self written function with lapply. So, I put the data frames in my example in a list, too. Then I "rbind" them to compute a frequency table.
df1 <- data.frame(rev(seq(12:0)), paste0("a=",sample(0:12, 13, replace=T)))
colnames(df1) <- c("k", "a")
df2 <- data.frame(rev(seq(12:0)), paste0("a=",sample(0:12, 13, replace=T)))
colnames(df2) <- c("k", "a")
list_df <- list(df1,df2)
df_combine<- plyr::ldply(list_df, rbind)
freq_foo <- table(df_combine$k,df_combine$a)
I get a frequency table of the following form.
a=0 a=11 a=12 a=2 a=5 a=6 a=7 a=8 a=3 a=9
1 1 0 0 0 0 0 0 1 0 0
2 1 0 0 0 0 0 0 0 0 1
3 1 0 0 0 0 1 0 0 0 0
4 0 0 0 1 0 1 0 0 0 0
5 0 0 0 1 1 0 0 0 0 0
6 0 0 0 0 0 0 1 0 0 1
7 0 1 1 0 0 0 0 0 0 0
8 1 0 0 0 0 1 0 0 0 0
9 0 0 0 0 0 0 2 0 0 0
10 0 0 1 0 1 0 0 0 0 0
11 1 1 0 0 0 0 0 0 0 0
12 0 0 0 0 0 0 1 0 1 0
13 1 0 1 0 0 0 0 0 0 0
I want to extend and manipulate my table in the following way:
First the table should go over a range of a=0 to a=15. So if there is a missing column, it should be added. And 2nd) I want to order the columns from 0 to 15.
For the first problem I tried
if(freq_foo$paste0("a=",0:15) == F){freq_foo$paste("a=",0:15) <- 0}
but this should work only for data frames and not for tables. Also. i've no idea how to order the columns with an ascending order. The data type isnt important to me because I just want to use the output for further calculations. So, it can also be a data frame instead of a table.
#convert freq_foo table to dataframe
df <- as.data.frame.matrix(freq_foo)
#add all zeros column for missing column name in 0:15 series
df[, paste0("a=", c(0:15)[!(c(0:15) %in% as.numeric(gsub(".*=(\\d+)", "\\1", names(df))))])] <- 0
#order columns from 0 to 15
df <- df[, order(as.numeric(gsub(".*=(\\d+)", "\\1", names(df))))]
Output is:
a=0 a=1 a=2 a=3 a=4 a=5 a=6 a=7 a=8 a=9 a=10 a=11 a=12 a=13 a=14 a=15
1 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0
2 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0
3 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0
4 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0
5 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0
6 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
7 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0
8 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0
9 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0
10 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
11 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
12 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0
13 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0
(Edit: Updated code after getting a requirement clarification from OP)

creating a larger matrix from smaller matrices in R

I have a series of text files in a folder called "Disintegration T1" which look like this:
> 1.txt
0 0 0 0 1
1 0 0 0 1
0 1 0 0 1
0 0 0 0 0
1 1 1 1 0
> 2.txt
0 1 1 0 1
0 0 1 1 1
1 1 0 1 1
1 1 1 0 1
0 0 0 0 1
> 3.txt
0 1 1 1
1 0 0 0
0 0 0 0
1 0 0 0
The files are all either 4X4 or 5X5. They must be read in as matrices, as the data is for social network analyses. My goal is to automate the process of putting these matrices into a larger matrix, so that these matrices are directly diagonal to each other, and 0s inputted in the blank spaces within the larger matrix. In this case the final result would look like:
> mega_matrix
0 0 0 0 1 0 0 0 0 0 0 0 0 0
1 0 0 0 1 0 0 0 0 0 0 0 0 0
0 1 0 0 1 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 1 1 0 1 0 0 0 0
0 0 0 0 0 0 0 1 1 1 0 0 0 0
0 0 0 0 0 1 1 0 1 1 0 0 0 0
0 0 0 0 0 1 1 1 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 1 1 1
0 0 0 0 0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 1 0 0 0
Thank you!
You want bdiag from the Matrix package:
library(Matrix)
bdiag(matrix1, matrix2, matrix3)
And to do the whole directory (thanks to #user20650 in the comments) :
bdiag(lapply(dir(), function(x){as.matrix(read.table(x))}))

using lappy and elseif command

Using R I have a table, lets say 'locations'
head(locations, n=10)
apillar fender fwheel fdoor compart rdoor rwheel boot
1 0 0 0 0 0 0 0 1
2 0 0 0 1 0 0 0 0
3 0 0 0 0 1 0 0 0
4 0 1 0 0 0 0 0 0
5 1 0 1 0 0 0 0 0
6 1 0 0 1 0 0 0 0
7 0 0 0 0 0 0 0 0
8 0 0 0 0 1 0 0 0
9 0 0 0 1 0 0 0 0
10 0 0 0 0 0 1 0 0
now i want to create a new variable "cat" which groups the impacts into category locations.
I have been using if, elseif and else command, but I cannot get it to work.
The command is:
cat <- lapply(locations, function(x) if (apillar|fender|fwheel == 1)print("front") else if (fdoor|compart|rdoor == 1)print("middle") else if(rwheel|boot ==1)print("rear") else print("NA")
such that cat should read rear, middle, middle, middle, front etc
When vectors of TRUE or FALSE statements are involved, I usually prefer not to work with if to avoid loops. I find conditional referencing to be more elegant in this case. See below.
locations <- read.table(header=TRUE, text=
"apillar fender fwheel fdoor compart rdoor rwheel boot
1 0 0 0 0 0 0 0 1
2 0 0 0 1 0 0 0 0
3 0 0 0 0 1 0 0 0
4 0 1 0 0 0 0 0 0
5 1 0 1 0 0 0 0 0
6 1 0 0 1 0 0 0 0
7 0 0 0 0 0 0 0 0
8 0 0 0 0 1 0 0 0
9 0 0 0 1 0 0 0 0
10 0 0 0 0 0 1 0 0")
locations$cat <- NA
within(locations,{
cat[apillar|fender|fwheel] <- "front"
cat[fdoor|compart|rdoor] <- "middle"
cat[rwheel|boot] <- "rear"
})
Result:
apillar fender fwheel fdoor compart rdoor rwheel boot cat
1 0 0 0 0 0 0 0 1 rear
2 0 0 0 1 0 0 0 0 middle
3 0 0 0 0 1 0 0 0 middle
4 0 1 0 0 0 0 0 0 front
5 1 0 1 0 0 0 0 0 front
6 1 0 0 1 0 0 0 0 middle
7 0 0 0 0 0 0 0 0 <NA>
8 0 0 0 0 1 0 0 0 middle
9 0 0 0 1 0 0 0 0 middle
10 0 0 0 0 0 1 0 0 middle
Cheers!
Corrected your own code:
locations$cat= with(locations, ifelse(apillar|fender|fwheel, "front", ifelse(fdoor|compart|rdoor,"middle",ifelse(rwheel|boot, "rear", "NA"))) )
> locations
apillar fender fwheel fdoor compart rdoor rwheel boot cat
1 0 0 0 0 0 0 0 1 rear
2 0 0 0 1 0 0 0 0 middle
3 0 0 0 0 1 0 0 0 middle
4 0 1 0 0 0 0 0 0 front
5 1 0 1 0 0 0 0 0 front
6 1 0 0 1 0 0 0 0 front
7 0 0 0 0 0 0 0 0 NA
8 0 0 0 0 1 0 0 0 middle
9 0 0 0 1 0 0 0 0 middle
10 0 0 0 0 0 1 0 0 middle
>

Resources