2016-11-10 1 views
0

J'essaye de grouper des points de données d'un NMDS dans ggplot en ajoutant des ellipses en utilisant la fonction ordiellipse suivant le conseil utile de this post. Cependant, bien que je n'obtiens pas de messages d'erreur ou d'avertissements, le calcul des données d'ellipse produit une trame de données vide. L'ensemble de données est disponible here, et mon code est le suivant:Trame de données vide lors du calcul des données d'ellipse avec ordiellipse de végétalien pour ggplot

library(vegan) 
library(ggplot2) 

setwd("C:") 
veg_matrix <- read.csv("161019_vegetation_matrix.csv",header=T); veg_matrix[2:123] <- lapply(veg_matrix[2:123],as.character); veg_matrix[2:123] <- lapply(veg_matrix[2:123],as.numeric) 
rownames(veg_matrix) <- veg_matrix[,1]; veg_matrix <- veg_matrix[,-1] # remove non-numeric rownames (=plot codes) from dataset 
speciescomp_NMDS = metaMDS(veg_matrix, k=2, trymax=100, distance="raup", na.rm=T) 
plot(speciescomp_NMDS,display="sites",type="n") 

# add grouping data 
plot_scores <- as.data.frame(scores(speciescomp_NMDS)) 
plot_scores$plot <- rownames(plot_scores);plot_scores <- cbind(plot_scores,data.frame(matrix(unlist(strsplit(plot_scores$plot,"_")),nrow=24,byrow=T)))[,-3]; colnames(plot_scores)[c(3,4)] <- c("summit","aspect") 
plot_scores$group <- "" 
plot_scores$group[plot_scores$summit=="BUF"|plot_scores$summit=="SES"] <- "low" 
plot_scores$group[plot_scores$summit=="CHA"|plot_scores$summit=="MIN"] <- "intermediate" 
plot_scores$group[plot_scores$summit=="CUO"|plot_scores$summit=="GAJ"] <- "high" 
plot_scores$group <- transform(plot_scores, as.factor(plot_scores$group)) 

# compute ellipse data 
ord <- ordiellipse(speciescomp_NMDS,plot_scores$group,display = "sites", kind = "sd", conf = .95, label=T) 

f_ellipse <- function (cov, center = c(0, 0), scale = 1, npoints = 100) 
{ 
    theta <- (0:npoints) * 2 * pi/npoints 
    Circle <- cbind(cos(theta), sin(theta)) 
    t(center + scale * t(Circle %*% chol(cov))) 
} 

df_ell_level <- data.frame() 
for(g in levels(plot_scores$group)){ 
    if(is.null(ord[[g]])) next 
    df_ell_level <- rbind(df_ell_level, 
        cbind(as.data.frame(with(plot_scores[plot_scores$group==g,], 
              f_ellipse(ord[[g]]$cov,ord[[g]]$center,ord[[g]]$scale))) 
         ,level=group)) 
} 

Toutes les idées sur la façon de traiter celui-ci sera chaudement apprécié!

+0

Les fichiers CSV n'utilisent pas ';' comme séparateur. Si c'est le cas, essayez 'read.csv2()'. Aussi; pourquoi tout le ';' à la fin des rangées. 'R! = C'. Le code échoue sur plusieurs fronts; i) qu'est-ce que 'df_ell_alt'? est-ce une faute de frappe et vous voulez dire 'rbind (df_ell_level, ...)'? ii) 'levels (plot_scores $ group)' est 'NULL' car' plot_scores $ group' * n'est pas un facteur *. La boucle ne fait jamais rien en conséquence. C'est un peu demander aux gens de déboguer votre code compliqué quand il est a) un désordre, et b) vous ne pouvez même pas distiller cela à un problème simple. –

Répondre

0

d'abord convertir group à un facteur

plot_scores <- transform(plot_scores, group = as.factor(group)) 

Si nous fixons maintenant votre boucle être:

df_ell_level <- data.frame() 
for(g in levels(plot_scores$group)){ 
    if(is.null(ord[[g]])) next 
    df_ell_level <- 
    rbind(df_ell_level, 
      cbind(as.data.frame(f_ellipse(ord[[g]]$cov, ord[[g]]$center, ord[[g]]$scale)), 
       level=g) 
     ) 
} 

Puis-je obtenir une trame de données avec 301 lignes. Mais j'ai coupé beaucoup de votre code inutile de l'appel, et vous ne voulez vraiment pas être ensemble dans une boucle comme ceci.

+0

Merci beaucoup d'avoir pris le temps et tous les commentaires utiles! 'As.factor' a résolu le problème. – jonfen