Renvoyer la première valeur rencontrée dans les différentes lignes d'une matrice

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

Laurent Boualit
Messages : 6
Enregistré le : 12 Sep 2017, 10:46

Renvoyer la première valeur rencontrée dans les différentes lignes d'une matrice

Messagepar Laurent Boualit » 12 Sep 2017, 11:33

Bonjour,

Je suis écologue et je travaille actuellement sur des données de Capture-Recapture

J'ai une matrice dans laquelle on retrouve en ligne des individus capturés, en colonnes des dates de session de capture et en intersections des sites sur lesquels on a capturés les individus. Les sessions de capture se font de janvier à juin et je souhaiterait ne prendre en compte que la première capture pour chaque individu.

Voici une partie de cette matrice :
http://hpics.li/4635daa


Tout d'abord j'ai transformé tous les "0" en Na. Ensuite j'ai supprimé la première colonne qui comporte les noms des individus. La nouvelle matrice est nommée "Hist_cap_sans_ind". Puis je suis partie dans une boucle :

Code : Tout sélectionner

  #Je crée une matrice dont les lignes contiennent les individus et une seule colonne contenant l'année 2010. Toutes les intersections contiennent des Na
  #Cette matrice contiendra pour chaque individu le premier site de capture de l'année 2010

  stock <- matrix(NA,nrow(name_ind),1)
  stock <- data.frame(stock)
  names(stock) <- "2010"
  rownames(stock) <- (rownames(name_ind))

 #Boucle permettant d'assigner le site

  for (i in 1:nrow(Hist_cap_sans_ind)){
  NonNA <-which(!is.na(Hist_cap_sans_ind)) # Je cherche les numéros de colonne des valeurs qui ne sont pas des NA
  firstNonNA <- min(NonNA) # Valeur du plus petit numéro de colonne qui correspond à la première valeur qui n'est pas un NA
  Val <- Hist_cap_sans_ind[i,firstNonNA] # Je récupère la valeur de la première intersection qui n'est pas un NA
 
     for (z in 1:nrow(stock))
       stock[z,1] <- Val # J'assigne à chaque intersection la valeur du premier site de rencontre
}


Bon, vu que je débute pas mal, les intersections de stock sont remplies de "J" ce qui correspond au premier site de capture du premier individu. Je me doute que l'ordre interne de ma boucle doit être mauvais. J'ai aussi essayé ça :

Code : Tout sélectionner

for (i in 1:nrow(Hist_cap_sans_ind)){
  for (j in 1:ncol(Hist_cap_sans_ind))
 
  NonNA <-which(!is.na(Hist_cap_sans_ind[i]))
  firstNonNA <- min(NonNA)
  stock[i] <-Hist_Capture[i,firstNonNA+1]
  }
 


Mais je récupère cette erreur :

Code : Tout sélectionner

Error: Column index must be at most 14 if positive, not Inf
In addition: Warning message:
In min(NonNA) : no non-missing arguments to min; returning Inf


Quelqu'un aurait-il une idée pour me faire avancer ?

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

Re: Renvoyer la première valeur rencontrée dans les différentes lignes d'une matrice

Messagepar Pierre-Yves Berrard » 12 Sep 2017, 12:30

Bonjour,

Afin que l'on puisse vous aider, pouvez-vous fournir un extrait des données sous un autre format qu'image ?

Par exemple :

Code : Tout sélectionner

dput(Hist_cap_sans_ind)

ou si c'est trop volumineux, les m premières lignes et n premières colonnes :

Code : Tout sélectionner

dput(Hist_cap_sans_ind[1:m, 1:n])

(plus de détails sur comment insérer les données ici)
PY

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

Re: Renvoyer la première valeur rencontrée dans les différentes lignes d'une matrice

Messagepar Michaël Delorme » 12 Sep 2017, 12:35

Pour bien comprendre : tu veux la date ou le site de première capture de chaque animal ?

Logez Maxime
Messages : 3138
Enregistré le : 26 Sep 2006, 11:35

Re: Renvoyer la première valeur rencontrée dans les différentes lignes d'une matrice

Messagepar Logez Maxime » 12 Sep 2017, 12:48

Bonjour,

Code : Tout sélectionner

tab <- structure(list(`10.02.10` = c(NA, NA, NA, NA, "F", NA, NA, NA,
NA, NA), `24.02.10` = c(NA, NA, NA, NA, NA, NA, NA, NA, "F",
NA), `01.03.10` = c(NA_character_, NA_character_, NA_character_,
NA_character_, NA_character_, NA_character_, NA_character_, NA_character_,
NA_character_, NA_character_), `02.03.10` = c(NA, NA, "J", NA,
NA, NA, NA, NA, NA, NA), `04.03.10` = c(NA, NA, NA, NA, "J",
NA, NA, NA, NA, "J")), .Names = c("10.02.10", "24.02.10", "01.03.10",
"02.03.10", "04.03.10"), row.names = c("18", "27", "31", "36",
"40", "41", "59", "110", "170", "185"), class = "data.frame")

library(tidyr)
library(dplyr)
gather(cbind(ID = rownames(tab), tab), "date", "site", -1) %>% group_by(ID) %>% filter(!is.na(site)) %>% top_n(1)
Selecting by valeur
Source: local data frame [4 x 3]
Groups: ID [4]

      ID     date  site
  <fctr>    <chr>  <chr>
1    170 24.02.10      F
2     31 02.03.10      J
3     40 04.03.10      J
4    185 04.03.10      J
Cordialement,
Maxime

Laurent Boualit
Messages : 6
Enregistré le : 12 Sep 2017, 10:46

Re: Renvoyer la première valeur rencontrée dans les différentes lignes d'une matrice

Messagepar Laurent Boualit » 12 Sep 2017, 12:54

Bonjour, merci pour votre aide.

Maxime, ça ne semble pas fonctionner par exemple :

Code : Tout sélectionner

3     40 04.03.10      J


Il renvoie J pour l'individu 40 alors que le premier site où nous l'avons capturé est le F.

Voici les 15 premières lignes et 13 premières colonnes de ma matrice:

Code : Tout sélectionner

Hist_cap-sans-ind <- structure(list(`10.02.10` = c(NA_character_, NA_character_, NA_character_,
NA_character_, NA_character_, NA_character_, NA_character_, NA_character_,
NA_character_, NA_character_, NA_character_, NA_character_, NA_character_,
NA_character_, NA_character_), `24.02.10` = c(NA_character_,
NA_character_, NA_character_, NA_character_, NA_character_, NA_character_,
NA_character_, NA_character_, NA_character_, NA_character_, NA_character_,
NA_character_, NA_character_, NA_character_, NA_character_),
    `25.02.10` = c(NA_character_, NA_character_, NA_character_,
    NA_character_, NA_character_, NA_character_, NA_character_,
    NA_character_, NA_character_, NA_character_, NA_character_,
    NA_character_, NA_character_, NA_character_, NA_character_
    ), `01.03.10` = c(NA_character_, NA_character_, NA_character_,
    NA_character_, NA_character_, NA_character_, NA_character_,
    NA_character_, NA_character_, NA_character_, NA_character_,
    NA_character_, NA_character_, NA_character_, NA_character_
    ), `02.03.10` = c(NA_character_, NA_character_, NA_character_,
    NA_character_, NA_character_, NA_character_, NA_character_,
    NA_character_, NA_character_, NA_character_, NA_character_,
    NA_character_, NA_character_, NA_character_, NA_character_
    ), `04.03.10` = c(NA_character_, NA_character_, NA_character_,
    NA_character_, NA_character_, NA_character_, NA_character_,
    NA_character_, NA_character_, NA_character_, NA_character_,
    NA_character_, NA_character_, NA_character_, NA_character_
    ), `12.03.10` = c("J", NA, NA, NA, NA, NA, NA, NA, NA, NA,
    NA, NA, NA, NA, NA), `15.03.10` = c(NA_character_, NA_character_,
    NA_character_, NA_character_, NA_character_, NA_character_,
    NA_character_, NA_character_, NA_character_, NA_character_,
    NA_character_, NA_character_, NA_character_, NA_character_,
    NA_character_), `18.03.10` = c(NA_character_, NA_character_,
    NA_character_, NA_character_, NA_character_, NA_character_,
    NA_character_, NA_character_, NA_character_, NA_character_,
    NA_character_, NA_character_, NA_character_, NA_character_,
    NA_character_), `21.03.10` = c(NA_character_, NA_character_,
    NA_character_, NA_character_, NA_character_, NA_character_,
    NA_character_, NA_character_, NA_character_, NA_character_,
    NA_character_, NA_character_, NA_character_, NA_character_,
    NA_character_), `24.03.10` = c(NA_character_, NA_character_,
    NA_character_, NA_character_, NA_character_, NA_character_,
    NA_character_, NA_character_, NA_character_, NA_character_,
    NA_character_, NA_character_, NA_character_, NA_character_,
    NA_character_), `25.03.10` = c(NA_character_, NA_character_,
    NA_character_, NA_character_, NA_character_, NA_character_,
    NA_character_, NA_character_, NA_character_, NA_character_,
    NA_character_, NA_character_, NA_character_, NA_character_,
    NA_character_), `30.03.10` = c(NA_character_, NA_character_,
    NA_character_, NA_character_, NA_character_, NA_character_,
    NA_character_, NA_character_, NA_character_, NA_character_,
    NA_character_, NA_character_, NA_character_, NA_character_,
    NA_character_)), .Names = c("10.02.10", "24.02.10", "25.02.10",
"01.03.10", "02.03.10", "04.03.10", "12.03.10", "15.03.10", "18.03.10",
"21.03.10", "24.03.10", "25.03.10", "30.03.10"), row.names = c(NA,
-15L), class = c("tbl_df", "tbl", "data.frame"))


Ce que je souhaite obtenir c'est le 1er site de capture.

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

Re: Renvoyer la première valeur rencontrée dans les différentes lignes d'une matrice

Messagepar Pierre-Yves Berrard » 12 Sep 2017, 13:15

Code : Tout sélectionner

apply(Hist_cap-sans-ind, 1, function(x) x[!is.na(x)][1])
PY

Laurent Boualit
Messages : 6
Enregistré le : 12 Sep 2017, 10:46

Re: Renvoyer la première valeur rencontrée dans les différentes lignes d'une matrice

Messagepar Laurent Boualit » 12 Sep 2017, 13:21

Bonjour Pierre-Yves,

Merci de ta réponse. Pourrais-tu m'expliquer rapidement cette partie s'il te plait ? :

Code : Tout sélectionner

function(x) x[!is.na(x)][1]


Quand je lance cette ligne j'obtient "J" en résultat qui j'imagine est le premier site de capture du premier individu.

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

Re: Renvoyer la première valeur rencontrée dans les différentes lignes d'une matrice

Messagepar Pierre-Yves Berrard » 12 Sep 2017, 13:23

C'est une fonction qui est appliquée à chaque ligne du tableau.
x étant une ligne, je lui dis de prendre le premier élément ([1]) non manquant (!is.na) de x
"apply" répète cette opération sur chaque ligne
PY

Logez Maxime
Messages : 3138
Enregistré le : 26 Sep 2006, 11:35

Re: Renvoyer la première valeur rencontrée dans les différentes lignes d'une matrice

Messagepar Logez Maxime » 12 Sep 2017, 13:29

Maxime, ça ne semble pas fonctionner par exemple :
Tu confonds mon tableau d'exemple avec le tien. Si tu appliques mon code a ton tableau :

Code : Tout sélectionner

gather(cbind(ID = rownames(Hist_cap_sans_ind), Hist_cap_sans_ind), "date", "site", -1) %>% group_by(ID) %>%
  filter(!is.na(site)) %>% top_n(1)
Selecting by site
Source: local data frame [1 x 3]
Groups: ID [1]

      ID     date  site
  <fctr>    <chr> <chr>
1      1 12.03.10     J
Ca fonctionne mais moins rapidement que celui de Pierre-Yves, voir un précédent post sur la question ;-)

Cordialement,
Maxime

Laurent Boualit
Messages : 6
Enregistré le : 12 Sep 2017, 10:46

Re: Renvoyer la première valeur rencontrée dans les différentes lignes d'une matrice

Messagepar Laurent Boualit » 12 Sep 2017, 13:29

Merci beaucoup, on m'avait dit qu' apply est plus efficace que les boucles. Je n'avais pas pris le temps de m'y intéresser. Va falloir que je me mette aux fonctions du coup !!!
Finalement ça fonctionne, je n'avais pas le bon Hist_cap_sans_ind.

Merci pour ses informations, reste à les faire fonctionner maintenant ;-)

Edit : ca fonctionne parfaitement, merci !!!

Logez Maxime
Messages : 3138
Enregistré le : 26 Sep 2006, 11:35

Re: Renvoyer la première valeur rencontrée dans les différentes lignes d'une matrice

Messagepar Logez Maxime » 12 Sep 2017, 13:32

Merci beaucoup, on m'avait dit qu' apply est plus efficace que les boucles
Ce sont des légendes urbaines, surtout quand il s'agit de la fonction apply qui est la plus lente de sa famille ...

Cordialement,
Maxime

Laurent Boualit
Messages : 6
Enregistré le : 12 Sep 2017, 10:46

Re: Renvoyer la première valeur rencontrée dans les différentes lignes d'une matrice

Messagepar Laurent Boualit » 12 Sep 2017, 13:42

Pierre-Yves, une idée pour faire le contraire, c'est à dire le dernier site de capture de chaque individu ?

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

Re: Renvoyer la première valeur rencontrée dans les différentes lignes d'une matrice

Messagepar Pierre-Yves Berrard » 12 Sep 2017, 13:58

On met la ligne en ordre inverse !

Code : Tout sélectionner

apply(mat, 1, function(x) rev(x[!is.na(x)])[1])
PY

Laurent Boualit
Messages : 6
Enregistré le : 12 Sep 2017, 10:46

Re: Renvoyer la première valeur rencontrée dans les différentes lignes d'une matrice

Messagepar Laurent Boualit » 12 Sep 2017, 13:59

Pierre-Yves Berrard a écrit :On met le vecteur dans l'ordre inverse !

Code : Tout sélectionner

apply(mat, 1, function(x) rev(x[!is.na(x)])[1])


Merci beaucoup !!!


Retourner vers « Questions en cours »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité