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 = " "))