Soustraction d'une liste d'espèces avec conditions

Postez ici vos questions, réponses, commentaires ou suggestions - Les sujets seront ultérieurement répartis dans les archives par les modérateurs

Modérateur : Groupe des modérateurs

germain vital
Messages : 26
Enregistré le : 24 Nov 2019, 13:54

Soustraction d'une liste d'espèces avec conditions

Messagepar germain vital » 13 Aoû 2020, 09:48

Bonjour à tous,

Je travaille sur un jeu de données avec des mousses et des hépatiques échantillonnées le long d'un gradient altitudinal. 11 altitudes ont été échantillonnées entre 350m et 2750m (tout les 200m).

La gamme altitudinale d'une espèce est définis comme l'aire entre l'altitude minimum et l'altitude maximum où celle-ci a été retrouvé. Pour ce faire, le postulat qu'une espèce est forcément présente entre ce minimum et ce maximum est nécessaire. Ce que j'aimerais est donc de vérifier que cela ne soit pas trop fort de café.

Je cherche donc (voir l'exemple de jeu de donné reproductible ci-dessous) à retrouver les espèces qui sont absente de TOUTES les altitudes entre leur maximum et minimum.

Cela sera peut être plus claire avec un exemple (1 présente 0 absente) :

350 m 550m 750m 950m 1150m
espèces A : 0 1 1 0 1
espèce B : 1 0 0 0 1
espèce C : 0 0 1 1 1

Dans cet exemple, je souhaite retrouver l'espèce B. Seulement, j'ai du mal à avoir un code afin d'arriver à cela. J'ai pensé à quelque chose de la sorte if_else(espèce, si la somme entre 1er "1" et dernier "1" = 0, alors considérer cette espèce). Mais je ne vois vraiment pas comment écrire cela.

J'espère que j'ai été assez claire dans mes explications, ci-contre un code reproductible (où ici AEROSUBPM est la catégorie d'espèce recherchée) :

Code : Tout sélectionner

> PA_brk%>%
+   dplyr::select(1:6)%>%
+   slice(1:10)%>%
+   dput()
structure(list(alti = c(350, 550, 750, 950, 1150, 1350, 1550,
1750, 1950, 2150), ACROEMER = c(0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L,
0L, 0L), ACROMEGA = c(0, 1, 1, 1, 1, 0, 1, 0, 0, 0), AEROSUBPM = c(0,
1, 0, 1, 0, 0, 0, 0, 0, 0), AMAZDIPL = c(0, 0, 0, 0, 1, 0, 0,
0, 0, 0), ANASAURI = c(0, 0, 1, 0, 0, 0, 1, 0, 1, 0)), row.names = c(NA,
-10L), class = "data.frame")


Merci d'avance pour votre aide !

Florent Aubry
Messages : 324
Enregistré le : 25 Juin 2010, 10:21

Re: Soustraction d'une liste d'espèces avec conditions

Messagepar Florent Aubry » 13 Aoû 2020, 10:45

Ton critère n'est pas clair et semble même paradoxal. Il faudrait que tu précises chaque variable.

Autre question : pourquoi utiliser un code lourd et plutôt abscons alors que ton exemple s'écrit simplement comme suit :

Code : Tout sélectionner

dput( PA_brk[1:10,1:6])
?

germain vital
Messages : 26
Enregistré le : 24 Nov 2019, 13:54

Re: Soustraction d'une liste d'espèces avec conditions

Messagepar germain vital » 13 Aoû 2020, 11:27

Mon critère de ? Paradoxal à quel niveau ?

J'ai en variable : l'altitude nommé "alti" représentant, dans le sous jeu de données fournit, 10 des 13 altitudes échantillonnés (tout les 200m d'un gradient altitudinal). Ensuite, j'ai les noms (ici des codes 4 premières du genre et 4 de l'espèce) de mes espèces (6 espèces sur un total de 246). Dans les cellules codées en 1 la présence de l'espèce à cette altitude, et en 0 sont absence.

Réponse à votre autre question : Il n'y a pas de raison particulière

Pierre-Yves Berrard
Messages : 1029
Enregistré le : 12 Jan 2016, 23:30

Re: Soustraction d'une liste d'espèces avec conditions

Messagepar Pierre-Yves Berrard » 13 Aoû 2020, 11:54

Il faut donc repérer les lignes qui suivent le motif suivant :

[suite de zéros, ou rien] 1 [suite de zéros, ou rien] 1 [suite de zéros, ou rien]

C'est ça ?
PY

Michaël Delorme
Messages : 67
Enregistré le : 04 Avr 2016, 10:21

Re: Soustraction d'une liste d'espèces avec conditions

Messagepar Michaël Delorme » 13 Aoû 2020, 11:56

Plus facile au format long : on ne garde que les données dans l'intervalle min-max (exclus) et on compte les 0

Code : Tout sélectionner

pa_brk <-
  structure(
    list(
      alti = c(350, 550, 750, 950, 1150, 1350, 1550,
               1750, 1950, 2150),
      ACROEMER = c(0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L,
                   0L, 0L),
      ACROMEGA = c(0, 1, 1, 1, 1, 0, 1, 0, 0, 0),
      AEROSUBPM = c(0,
                    1, 0, 1, 0, 0, 0, 0, 0, 0),
      AMAZDIPL = c(0, 0, 0, 0, 1, 0, 0,
                   0, 0, 0),
      ANASAURI = c(0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
    ),
    row.names = c(NA,
                  -10L),
    class = "data.frame"
  )

pa_brk %>%
  pivot_longer(-1, names_to = "espece", values_to = "presence") %>%
  group_by(espece) %>%
  filter(alti < max(alti[presence == 1]), alti > min(alti[presence == 1])) %>%
  summarise(nodata = sum(presence) == 0) %>%
  filter(nodata) %>%
  select(espece)

Pierre-Yves Berrard
Messages : 1029
Enregistré le : 12 Jan 2016, 23:30

Re: Soustraction d'une liste d'espèces avec conditions

Messagepar Pierre-Yves Berrard » 13 Aoû 2020, 12:06

Un variante à la proposition de Michaël, en observant que les espèces à repérer auront toujours deux 1.

Code : Tout sélectionner

pa_brk %>%
  pivot_longer(-1, names_to = "espece", values_to = "presence") %>%
  group_by(espece) %>%
  summarise(sum_presence = sum(presence)) %>%
  filter(sum_presence == 2) %>%
  select(espece)
PY

Pierre-Yves Berrard
Messages : 1029
Enregistré le : 12 Jan 2016, 23:30

Re: Soustraction d'une liste d'espèces avec conditions

Messagepar Pierre-Yves Berrard » 13 Aoû 2020, 12:10

Et la même idée sans {tidyverse} :

Code : Tout sélectionner

fort_de_cafe <- sapply(pa_brk[-1], function(x) sum(x) == 2)

#> ACROEMER  ACROMEGA AEROSUBPM  AMAZDIPL  ANASAURI
#>    FALSE     FALSE      TRUE     FALSE     FALSE
PY

Michaël Delorme
Messages : 67
Enregistré le : 04 Avr 2016, 10:21

Re: Soustraction d'une liste d'espèces avec conditions

Messagepar Michaël Delorme » 13 Aoû 2020, 12:29

Belle concision...

germain vital
Messages : 26
Enregistré le : 24 Nov 2019, 13:54

Re: Soustraction d'une liste d'espèces avec conditions

Messagepar germain vital » 13 Aoû 2020, 13:10

Effectivement je n'avais pas pensé à cette technique de sélectionner qu'uniquement l'intérieur des intervalles sans les limites et d'en faire la somme ! Merci beaucoup pour votre aide !

Petite question, le "-1" quand il s'agit de sélectionner la colonne veut dire toutes les colonnes sauf la première ?

Mickael Canouil
Messages : 1315
Enregistré le : 04 Avr 2011, 08:53
Contact :

Re: Soustraction d'une liste d'espèces avec conditions

Messagepar Mickael Canouil » 13 Aoû 2020, 13:39

Bonjour,

le -1 ici consiste à exclure le premier élément de la liste, dans le cas d'un data.frame (une liste dont les éléments font la même dimensions), cela exclue la colonne dont l'indice est 1.
Pierre-Yves Berrard a écrit :Et la même idée sans {tidyverse} :

Code : Tout sélectionner

fort_de_cafe <- sapply(pa_brk[-1], function(x) sum(x) == 2)

#> ACROEMER  ACROMEGA AEROSUBPM  AMAZDIPL  ANASAURI
#>    FALSE     FALSE      TRUE     FALSE     FALSE


pour faire encore plus court (pas forcément plus performant selon le jeu de données) :

Code : Tout sélectionner

colSums(pa_brk[-1]) == 2
#>  ACROEMER  ACROMEGA AEROSUBPM  AMAZDIPL  ANASAURI 
#>     FALSE     FALSE      TRUE     FALSE     FALSE  

Cordialement,
Mickaël
mickael.canouil.fr | rlille.fr

Pierre-Yves Berrard
Messages : 1029
Enregistré le : 12 Jan 2016, 23:30

Re: Soustraction d'une liste d'espèces avec conditions

Messagepar Pierre-Yves Berrard » 13 Aoû 2020, 13:58

[digression]
@Mickael : par curiosité, tu as un exemple ou colSums serait moins performant que sapply(., sum) ?
[\digression]
PY

Mickael Canouil
Messages : 1315
Enregistré le : 04 Avr 2011, 08:53
Contact :

Re: Soustraction d'une liste d'espèces avec conditions

Messagepar Mickael Canouil » 13 Aoû 2020, 14:28

Dans le cas présent par exemple.

colSums est plus efficace sur des matrices.
J'en profite pour glisser le vapply.

Code : Tout sélectionner

pa_brk <- structure(
  list(
    alti = c(350, 550, 750, 950, 1150, 1350, 1550, 1750, 1950, 2150),
    ACROEMER = c(0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L),
    ACROMEGA = c(0, 1, 1, 1, 1, 0, 1, 0, 0, 0),
    AEROSUBPM = c(0, 1, 0, 1, 0, 0, 0, 0, 0, 0),
    AMAZDIPL = c(0, 0, 0, 0, 1, 0, 0, 0, 0, 0),
    ANASAURI = c(0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
  ),
  row.names = c(NA, -10L),
  class = "data.frame"
)

Code : Tout sélectionner

plot(bench::mark(
  vapply = vapply(pa_brk[-1], function(x) sum(x) == 2, logical(1)),
  sapply = sapply(pa_brk[-1], function(x) sum(x) == 2),
  colSums = colSums(pa_brk[-1]) == 2
))

Image

Code : Tout sélectionner

pa_brk1 <- as.matrix(pa_brk[-1])
plot(bench::mark(
  apply = apply(pa_brk1, 2, function(x) sum(x) == 2),
  colSums = colSums(pa_brk1) == 2
)) 

Image
Mickaël
mickael.canouil.fr | rlille.fr

Pierre-Yves Berrard
Messages : 1029
Enregistré le : 12 Jan 2016, 23:30

Re: Soustraction d'une liste d'espèces avec conditions

Messagepar Pierre-Yves Berrard » 13 Aoû 2020, 20:13

Merci pour cette réponse détaillée !
PY


Retourner vers « Questions en cours »

Qui est en ligne

Utilisateurs parcourant ce forum : Google [Bot] et 1 invité