我正在尝试将Simpson的多样性指数应用于许多不同的数据集,其中捕获了可变数量的物种('nuse')。因此,我正在尝试构建能够自动处理此问题的代码,而无需在每次执行时手动构建公式。手动公式的示例数据集如下:
diverse <- data.frame(nuse1=c(0,20,40,20), nuse2=c(5,5,3,20), nuse3=c(0,2,8,20), nuse4=c(5,8,2,20), total=c(10,35,53,80))
simp <- function(x) {
total <- x[,"total"]
nuse1 <- x[,"nuse1"]
nuse2 <- x[,"nuse2"]
nuse3 <- x[,"nuse3"]
nuse4 <- x[,"nuse4"]
div <- round(((1-(((nuse1*(nuse1 - 1)) + (nuse2*(nuse2 - 1)) + (nuse3*(nuse3 - 1)) + (nuse4*(nuse4 - 1)))/(total*(total - 1))))),digits=4)
return(div)
}
diverse$Simpson <- simp(diverse)
diverse
你可以看到这很好用。但是,我怎么能够创建一个可以自动调整到9种物种的功能(所以直到nuse9)?
我已经尝试了粘贴功能+ as.formula,如Formula with dynamic number of variables所示;然而,这是我努力奋斗的(nuse1 *(nuse1 - 1))的扩展形式。有人有什么建议吗?感谢。
答案 0 :(得分:1)
如下:
diverse <- data.frame(nuse1=c(0,20,40,20), nuse2=c(5,5,3,20), nuse3=c(0,2,8,20), nuse4=c(5,8,2,20), total=c(10,35,53,80))
simp <- function(x, species) {
spcs <- grep(species, colnames(x)) # which column names have "nuse"
total <- rowSums(x[,spcs]) # sum by row
div <- round(1 - rowSums(apply(x[,spcs], 2, function(s) s*(s-1))) / (total*(total - 1)), digits = 4)
return(div)
}
diverse$Simpson2 <- simp(diverse, species = "nuse")
diverse
# nuse1 nuse2 nuse3 nuse4 total Simpson2
# 1 0 5 0 5 10 0.5556
# 2 20 5 2 8 35 0.6151
# 3 40 3 8 2 53 0.4107
# 4 20 20 20 20 80 0.7595
它所做的就是找出哪些列以“nuse”或您在数据集中拥有的任何其他物种开头。它构造函数中的“总”值,并且不需要数据集中的总列。