심심해서 만들어 보았다.
지수는 총 3개(Margalef 's Richness index, Pielou's evenness index, Shannon-Wienner index )를 계산하였다.
| 예제 데이터
sam1 = c(2,8,1,1,3)
sam2 = c(3,7,3,1,0)
sam3 = c(10,3,0,0,2)
df <- data.frame(sam1, sam2, sam3)
df
rownames(df) <- c("See_holly",
"Sand_couch",
"Sea_bindweed",
"Sporobolus pungens",
"Echinophora_spinosa")
| 계산 코드
초기 코드
ri_sh_ev <- function(DF){
DFF <- DF
# richness
DFF[(nrow(DFF) + 1),] <- 0
rownames(DFF)[nrow(DFF)] <- "Richness"
for (i in colnames(DF) ){
rich <- (length(DF[DF[i] != 0,i ])-1)/log(sum(DF[i]))
DFF[nrow(DFF), i] <- rich
}
# shannon
DFF[(nrow(DFF) + 1),] <- 0
rownames(DFF)[nrow(DFF)] <- "shannon"
for (i in colnames(DF) ){
a <- DF[DF[i] != 0,i ]
b <- a/sum(a)
shan <- -sum(b*log(b))
DFF[nrow(DFF), i] <- shan
}
# eveness
DFF[(nrow(DFF) + 1),] <- 0
rownames(DFF)[nrow(DFF)] <- "eveness"
for (i in colnames(DF) ){
a <- DF[DF[i] != 0,i ]
n = length(a)
sh = DFF["shannon",i]
s = sum(a)
even <- sh/log(s)
DFF[nrow(DFF), i] <- even
}
return(print(DFF))
}
코드는 전혀 깔끔하지 않고 줄일 수 있는 부분이 많다. 특히 반복된 부분이 있는데, 이는 for문으로 해결하거나 하나로 통합해서 처리하는게 좋을 것 같다.
개선 후
DF = df
DFF <-DF
n = nrow(DF)
DFF[(n+1):(n+3),] <- 0
rownames(DFF)[(n+1):(n+3)] <- c("Richness", "Shannon", "Eveness")
for (i in colnames(DF) ){
a <- DF[DF[i] != 0,i ]
# richness
rich <- (length(a)-1)/log(sum(a))
DFF["Richness", i] <- rich
# shannon
shan <- -sum( (a/sum(a)) * log(a/sum(a)) )
DFF["Shannon", i] <- shan
# eveness
sh = DFF["Shannon",i]
even <- sh/log(sum(a))
DFF["Eveness", i] <- even
}
return(print(DFF))
}
| 결과
df.2 <- ri_sh_ev(df)
df.2
# sam1 sam2 sam3
# See_holly 2.0000000 3.0000000 10.0000000
# Sand_couch 8.0000000 7.0000000 3.0000000
# Sea_bindweed 1.0000000 3.0000000 0.0000000
# Sporobolus pungens 1.0000000 1.0000000 0.0000000
# Echinophora_spinosa 3.0000000 0.0000000 2.0000000
# Richness 1.4770775 1.1367695 0.7385387
# Shannon 1.2868726 1.1952684 0.8608514
# Eveness 0.4752026 0.4529149 0.3178861
샘플의 개수가 정수에서 실수로 변해버린게 단점이지만, 종 다양성 지수는 잘 계산되었다.
반응형