Manipulation de données et de tableaux

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

Cyrielle Jac
Messages : 55
Enregistré le : 13 Mar 2017, 08:30

Manipulation de données et de tableaux

Messagepar Cyrielle Jac » 10 Jan 2018, 14:24

Bonjour à tous,

Alors voilà j'ai deux tableaux de données, un premier avec des espèces et de biomasses :

Especes Biomasse
Acanthuridae 10
Caranx melampygus 3
Pennatulidae 5
Cancer 10

Et un second avec la classification des espèces

Embranchement Classe Ordre Famille Genre Especes
Chordata Actinoperygii Perciformes Acanthuridae Acanthurus Acanthurus leucosternon
Chordata Actinoperygii Perciformes Carangidae Caranx Caranx melampygus
Arthropoda Malacostraca Decapoda Cancridae Cancer Cancer pagurus
(....)

Je veux remettre cette classification pour chacune de mes espèces du tableau 1.
J'ai donc fait un merge :
donnee<-merge(tab1, tab2, by.x="Especes", by.y="Especes", all.x = T)

Le problème c'est que dans la colonne "Especes" de mon tableau 1, j'ai aussi des famille, des genre ou des ordres et je voudrais donc un code qui me permette de compléter les colonnes qui manque. Par exemple si c'est la famille, il faut qu'il me remplisse les colonnes Ordre, classe, embranchement mais si c'est au niveau de l'ordre il me faut juste la classe et l'embranchement et des NA dans les autres colonnes.

J'ai pensé faire des boucles if ou avec des ifelse mais mes tableaux ne faisant pas la même longueur cela ne fonctionne pas (ou alors c'est moi qui n'utilises pas le bon code).
Avez-vous des idées?

Cyrielle

Dominique Soudant
Messages : 758
Enregistré le : 23 Avr 2008, 11:12
Contact :

Re: Manipulation de données et de tableaux

Messagepar Dominique Soudant » 10 Jan 2018, 15:15

Le traitement des données taxonomiques :
Apocalypse now a écrit :L'Horreur ...
Gandalf a écrit :Fuyez pauvres fous!
Bref ...
Je pense que ce que tu poses là n'est que le début de ton PB. Dans un situation similaire, ici, on a fini par faire une table de correspondance. Une autre solution (également mise en œuvre dans mon service) est l'interrogation du WORMS, beaucoup plus lourd à mettre en place. Mais ce n'est que le début de tes PBS parce que dans ce qui va suivre tu vas vouloir calculer des indices de diversités, de la richesse spécifique, des indices d'abondance. Et pour faire tout ça il faut avoir des niveaux taxonomiques comparables (calculer de la richesse spécifique avec des familles ? 8o ). Je te renvoie à la thèse de Tania Hernandez Farinas (sur le net) qui a défini et travaillé avec des "unités taxonomiques".

Bon courage.
@+

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

Re: Manipulation de données et de tableaux

Messagepar Mickael Canouil » 10 Jan 2018, 15:33

Bonjour,

n'est-il pas possible d'avoir dans la "tab1", une colonne indiquant ce qui se trouve dans "espèces"?
Et d'où vient l'idée farfelue de mélanger le type d'information dans cette colonne?

Cordialement,
PS: je n'ai jamais travaillé avec ce type de données.
Mickaël
mickael.canouil.fr | rlille.fr

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

Re: Manipulation de données et de tableaux

Messagepar Pierre-Yves Berrard » 10 Jan 2018, 15:50

Mickael Canouil a écrit :n'est-il pas possible d'avoir dans la "tab1", une colonne indiquant ce qui se trouve dans "espèces"?


On a pensé à la même chose, Mickael :

Code : Tout sélectionner

rang <- function(chaine) {
  for (nm in names(tab2)) if (chaine %in% tab2[[nm]]) return(nm)
  NA
}
tab1$Rang <- sapply(tab1$Especes, rang)

PS: n'étant pas non plus biologiste, pardonnez-moi si la dénomination Rang est incorrecte.
PS2: je pense qu'il faudra appeler la colonne 1 du premier tableau autrement, ça risque de créer la confusion par la suite.
PY

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

Re: Manipulation de données et de tableaux

Messagepar Pierre-Yves Berrard » 10 Jan 2018, 17:12

Une fois qu'on a le rang dans tab1, on peut créer une autre fonction qui récupère les rangs supérieurs à une "espèce" (au sens de tab1) donnée :

Code : Tout sélectionner

categ_sup <- function(chaine, rang) {
  if (is.na(rang)) return(rep(NA, 6))
  # première ligne contenant chaine dans tab2
  n <- which(tab2[[rang]] == chaine)[1]
  # m premiers éléments dans ligne n
  rang_num <- setNames(1:6, names(tab2))
  res <- unlist(tab2[n, seq(rang_num[rang])])
  # complete à 6 avec NA
  res <- c(res, rep(NA, 6 - rang_num[rang]))
  # ajoute nom de colonnes
  names(res) <- names(tab2)
  res
}

Utilisation :

Code : Tout sélectionner

res <- mapply(categ_sup, tab1$Especes, tab1$Rang, SIMPLIFY = FALSE)
do.call(rbind, res)
PY

Dominique Soudant
Messages : 758
Enregistré le : 23 Avr 2008, 11:12
Contact :

Re: Manipulation de données et de tableaux

Messagepar Dominique Soudant » 10 Jan 2018, 17:45

Mickael Canouil a écrit :Et d'où vient l'idée farfelue de mélanger le type d'information dans cette colonne?
On ne maîtrise pas le niveau taxonomique d'identification des organismes. On voudrait tout avoir au niveau de l'espèce. Mais les personnes en charge des comptages vont pouvoir identifier tel organisme observé au niveau de la famille et tel autre au niveau du genre et tel autre au niveau de l'espèce. D'où des listes faunistiques ou floristiques à des niveaux taxonomiques multiples ...
@+

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

Re: Manipulation de données et de tableaux

Messagepar Pierre-Yves Berrard » 11 Jan 2018, 08:31

Il y a avait une erreur dans mon précédent message ; j'ai édité.
PY

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

Re: Manipulation de données et de tableaux

Messagepar Logez Maxime » 12 Jan 2018, 08:48

Bonjour,

Une solution sans passer par le niveau d'information mais en ne servant que des deux tableaux à notre disposition :

Code : Tout sélectionner

# bio : le tableau avec la biomasse
bio <- structure(list(Especes = structure(c(1L, 3L, 4L, 2L), .Label = c("Acanthuridae",
"Cancer", "Caranx melampygus", "Pennatulidae"), class = "factor"),
    Biomasse = c(10L, 3L, 5L, 10L)), .Names = c("Especes", "Biomasse"
), class = "data.frame", row.names = c(NA, -4L))

# taxo : le tableau avec la taxonomie
taxo <- structure(list(Embranchement = structure(c(2L, 2L, 1L), .Label = c("Arthropoda",
"Chordata"), class = "factor"), Classe = structure(c(1L, 1L,
2L), .Label = c("Actinoperygii", "Malacostraca"), class = "factor"),
    Ordre = structure(c(2L, 2L, 1L), .Label = c("Decapoda", "Perciformes"
    ), class = "factor"), Famille = structure(c(1L, 3L, 2L), .Label = c("Acanthuridae",
    "Cancridae", "Carangidae"), class = "factor"), Genre = structure(c(1L,
    3L, 2L), .Label = c("Acanthurus", "Cancer", "Caranx"), class = "factor"),
    Especes = structure(c(1L, 3L, 2L), .Label = c("Acanthurus leucosternon",
    "Cancer pagurus", "Caranx melampygus"), class = "factor")), .Names = c("Embranchement",
"Classe", "Ordre", "Famille", "Genre", "Especes"), row.names = c(NA,
-3L), class = "data.frame")

taxo <- as.matrix(taxo)

m1 <- match(bio$Especes, taxo)

auxi <- nrow(taxo)

nl <- m1 %% auxi

nl[nl %in% 0] <- auxi

taxo2 <- taxo[nl,]

auxi2 <- ncol(taxo)

nc <- findInterval(m1, c(0, auxi*seq_len(ncol(taxo))) + 0.5)

for (i in seq_along(nc)) {
  if (is.na(nc[i]) || nc[i]==auxi2)
    next
  taxo2[i, (nc[i]+1):auxi2] <- NA
 }

taxo2 <- as.data.frame(taxo2)
res <- cbind(taxo2, bio[, "Biomasse", drop = FALSE])

res
  Embranchement        Classe       Ordre      Famille  Genre           Especes Biomasse
1      Chordata Actinoperygii Perciformes Acanthuridae   <NA>              <NA>       10
2      Chordata Actinoperygii Perciformes   Carangidae Caranx Caranx melampygus        3
3          <NA>          <NA>        <NA>         <NA>   <NA>              <NA>        5
4    Arthropoda  Malacostraca    Decapoda    Cancridae Cancer              <NA>       10
Cordialement,
Maxime

Cyrielle Jac
Messages : 55
Enregistré le : 13 Mar 2017, 08:30

Re: Manipulation de données et de tableaux

Messagepar Cyrielle Jac » 15 Jan 2018, 09:24

Bonjour,

Merci pour vos réponses à tous.
Maxime ta technique m'intéresse mais le problème c'est qu'il s'agit là d'un extrait de mes tableaux où j'ai environ 480 espèces. Il me parait donc impossible d'écrire à la main toutes les espèces présentes pour le .Label de la fonction structure :
.Label = c("Acanthuridae","Cancer", "Caranx melampygus", "Pennatulidae")

Est-il possible de faire autrement?

Cordialement,

Cyrielle

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

Re: Manipulation de données et de tableaux

Messagepar Logez Maxime » 15 Jan 2018, 09:37

Bonjour,

l'idée n'est pas de récrire le .Label, etc. Toutes ces lignes de codes :

Code : Tout sélectionner

bio <- structure(list(Especes = structure(c(1L, 3L, 4L, 2L), .Label = c("Acanthuridae",
"Cancer", "Caranx melampygus", "Pennatulidae"), class = "factor"),
    Biomasse = c(10L, 3L, 5L, 10L)), .Names = c("Especes", "Biomasse"
), class = "data.frame", row.names = c(NA, -4L))

# taxo : le tableau avec la taxonomie
taxo <- structure(list(Embranchement = structure(c(2L, 2L, 1L), .Label = c("Arthropoda",
"Chordata"), class = "factor"), Classe = structure(c(1L, 1L,
2L), .Label = c("Actinoperygii", "Malacostraca"), class = "factor"),
    Ordre = structure(c(2L, 2L, 1L), .Label = c("Decapoda", "Perciformes"
    ), class = "factor"), Famille = structure(c(1L, 3L, 2L), .Label = c("Acanthuridae",
    "Cancridae", "Carangidae"), class = "factor"), Genre = structure(c(1L,
    3L, 2L), .Label = c("Acanthurus", "Cancer", "Caranx"), class = "factor"),
    Especes = structure(c(1L, 3L, 2L), .Label = c("Acanthurus leucosternon",
    "Cancer pagurus", "Caranx melampygus"), class = "factor")), .Names = c("Embranchement",
"Classe", "Ordre", "Famille", "Genre", "Especes"), row.names = c(NA,
-3L), class = "data.frame")
Ne servaient uniquement à donner les codes R pour la création des deux tableaux que tu avais donné en exemple, pour que tout un chacun puisse les recopier dans sa console et tester le script que j'ai écrit à partir des deux objets bio et taxo.

Toi en pratique tu remplaces ces deux objets par tes données que tu importes à partir de ton fichier.
"taxo" sera un objet issu de l'import de ton fichier de taxonomie via une commande comme read.table.
Idem avec bio qui sera issu de l'import de ton fichier contenant les biomasses.

Cordialement,
Maxime

Cyrielle Jac
Messages : 55
Enregistré le : 13 Mar 2017, 08:30

Re: Manipulation de données et de tableaux

Messagepar Cyrielle Jac » 15 Jan 2018, 10:28

Ah exact! Merci beaucoup pour l'aide

Cyrielle

Cyrielle Jac
Messages : 55
Enregistré le : 13 Mar 2017, 08:30

Re: Manipulation de données et de tableaux

Messagepar Cyrielle Jac » 15 Jan 2018, 14:45

Bonjour,

Le tableau que j'obtiens semble être juste mais une erreur s'affiche tout de même après ces lignes de codes :
nc <- findInterval(m1, c(0, auxi2*seq_len(ncol(taxo))) + 0.5)
> for (i in seq_along(nc)) {
+ if (is.na(nc[i]) || nc[i]==auxi2)
+ next
+ taxo2[i, (nc[i]+1):auxi2] <- NA
+ }
Error in `[<-`(`*tmp*`, i, (nc[i] + 1):auxi2, value = NA) :
subscript out of bounds

Cette erreur indique bien que les cases "vides" n'ont pas été complétées par des NA?
Comment remédier à cette erreur?

Cordialement

Cyrielle

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

Re: Manipulation de données et de tableaux

Messagepar Mickael Canouil » 15 Jan 2018, 14:53

Bonjour,

l'erreur indique que votre indice (ligne ou colonne) n'existe pas dans la matrice.

Code : Tout sélectionner

x <- matrix(rnorm(4), nrow = 2, ncol = 2)

x[, 3]
Error in x[, 3] : subscript out of bounds


Il y a donc un problème de définition d'un indice, soit dans les conditions soit dans le "for"
Mickaël
mickael.canouil.fr | rlille.fr

Cyrielle Jac
Messages : 55
Enregistré le : 13 Mar 2017, 08:30

Re: Manipulation de données et de tableaux

Messagepar Cyrielle Jac » 26 Jan 2018, 10:45

Bonjour à tous,

J'ai encore un souci concernant la manipulation de tableaux. J'ai encore une fois deux tableaux, le premier comportant des "code espèces" et les noms d'espèces correspondants. Je vous mets les codes pour faire les 2 tableaux

code_sp<-c("CARMEL","CANPAG", "ACTSPP", "ABRVER")
nom_sp <- c("Caranx melampygus", "Cancer pagurus", "Abralia veranyi", "Actinauge")
tab1<- cbind(code_sp, nom_sp)

Et le tableau 2 comporte les années et les stations échantillonnées et les espèces et leur biomasse à chaque station

annee<- c(2012, 2015, 2015, 2011, 2011, 2011, 2013, 2016)
stations <- c(1, 4, 3, 1, 1, 1, 6, 12)
code_sp <- c("CANPAG", "ABRVER", "ABRVER", "CARMEL","CANPAG", "ACTSPP", "ABRVER", "ACTSPP")
biomasse <- c( 14, 10, 2, 36, 25, 10, 7, 8)
tab2<- cbind(annee, stations, code_sp, biomasse)

Et du coup je veux que dans le tab2, pour chaque code_sp, il me rajoute la colonne "nom_sp" du tableau 1. J'ai donc fait un merge :

donnee<-merge(tab2, tab1, by= code_sp)

Sauf que du coup mon tableaux final contient 300 lignes que mon tab2 (à la base ce tableau à 24 000 lignes). Je pense que c'est dû à la présence de doublons puisque la même espèce (et donc le même code_sp) est présente plusieurs fois dans le tab2 puisque elle a pu être vue dans différentes stations la même année et aussi à des années différentes.

Avez-vous une solution pour me permettre de "coller" mes deux tableaux?

Bonne journée

Cyrielle

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

Re: Manipulation de données et de tableaux

Messagepar Logez Maxime » 26 Jan 2018, 13:12

Bonjour,

Dans la fonction merge, tu peux spécifier si tu veux faire la jointure par rapport à l'un des deux tableaux (jointure left join ou right join) en spécifiant all.x = TRUE ou all.y = TRUE ou encore all = TRUE.

Sinon tu peux te servir de la fonction match qui est à la base de la fonction merge :

Code : Tout sélectionner

tab2$nom_sp <- tab1[match(tab2$code_sp, tab1$code_sp, nomatch =NA),"nom_sp"]
Cordialement,
Maxime


Retourner vers « Questions en cours »

Qui est en ligne

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