J'ai un fichier de données avec le couvert végétal par espèce (~ 80 espèces au total) dans 120 parcelles. Je veux trouver quelles espèces (par ordre décroissant de pourcentage de couverture) sont responsables d'au moins 80% du couvert végétal.
Par exemple:
Species Plot 1 A B Plot 2 C B A Plot 3 A
Donc le résultat sera:
Species A Species B Species C Species D Plot 1 50% 35% 10% 5% Plot 2 20% 30% 40% 10% Plot 3 85% 5% 15% 0%
etc.
Comment est-ce possible?
3 Réponses :
Solution rapide (peut être grandement améliorée, mais je vous laisse cela). Disons que ce sont vos données:
for(i in 1:nrow(species)){ Plot_i <- species[i, ] order_i <- sort(Plot_i, decreasing = T) j <- 1 while(sum(order_i[1:j])<threshold){ j <- j + 1 } print(names(order_i[1:j])) }
Maintenant, définissons votre seuil (disons, 80%):
threshold <- 80
Enfin, un réponse en boucle:
species <- data.frame(Species_A = c(50, 20, 80), Species_B = c(35, 30, 5), Species_C = c(10, 40, 15), Species_D = c(5, 10, 0)) row.names(species) <- c("Plot 1", "Plot 2", "Plot 3")
Veuillez noter que:
-Cela imprime la réponse, mais ne l'assigne pas à un objet
-Vous devriez éviter d'utiliser pour
et tandis que
les boucles dans R, car la famille apply
fonctionne généralement plus clairement et plus rapidement
-Je suppose que votre base de données ne contient que des chiffres, pas le symbole bizarre%, ce qui posera beaucoup de problèmes
Je ne sais pas comment faire la dernière étape, mais cela pourrait vous aider un peu à avancer:
library(tidyr) library(dplyr) #data df <- structure(list(Plot = c("Plot1", "Plot2", "Plot3", "Plot1", "Plot2", "Plot3", "Plot1", "Plot2", "Plot3", "Plot1", "Plot2", "Plot3" ), Species = structure(c(1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 4L, 4L), .Label = c("Species.A", "Species.B", "Species.C", "Species.D"), class = "factor"), Measurement = c(50L, 20L, 85L, 35L, 30L, 5L, 10L, 40L, 15L, 5L, 10L, 0L)), row.names = c(NA, -12L), class = "data.frame") #go from wide to long data df <- gather(df, Species, Measurement, Species.A:Species.D, factor_key = TRUE) #order values per group (highest measurements first) df <- df[order(df$Plot, df$Measurement, decreasing = TRUE),] #calculate the cumulative measurements df <- df %>% group_by(Plot) %>% mutate(Cumulative = ave(Measurement, Plot, FUN = cumsum)) df
Voici une autre approche utilisant tidyverse
.
Tout d'abord, mettez vos colonnes Species
au format long avec pivot_longer
. Ensuite, dans chaque Tracé
, arrangez les pourcentages par ordre décroissant pour calculer la somme cumulée avec arrange
.
Vous pouvez utiliser slice code > prendre des pourcentages jusqu'au franchissement du seuil de 80% du couvert végétal minimum. Enfin, vous pouvez utiliser
récapituler
pour rassembler les Espèces
pour chaque Plot
.
df <- structure(list(Plot = c("Plot_1", "Plot_2", "Plot_3"), Species_A = c(50L, 20L, 85L), Species_B = c(35L, 30L, 5L), Species_C = c(10L, 40L, 15L), Species_D = c(5L, 10L, 0L)), class = "data.frame", row.names = c(NA, -3L))
Sortie
# A tibble: 3 x 2 Plot Species <chr> <chr> 1 Plot_1 Species_A Species_B 2 Plot_2 Species_C Species_B Species_A 3 Plot_3 Species_A
Données
library(tidyverse) df %>% pivot_longer(cols = starts_with("Species")) %>% group_by(Plot) %>% arrange(desc(value)) %>% dplyr::mutate(cum_value = cumsum(value)) %>% slice(1:min(which(cum_value >= 80))) %>% dplyr::summarise(Species = paste(name, collapse = " "))