remplir 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

Guillaume Dramais
Messages : 39
Enregistré le : 25 Sep 2018, 00:04

remplir une matrice

Messagepar Guillaume Dramais » 25 Avr 2019, 22:05

Bonjour,

Je voudrais créer une matrice à partir d'un data frame qui contient une colonne avec le nombre de valeur souhaitées (N) et une autre colonne avec la valeur à répéter N fois (subvalue).

Code : Tout sélectionner

subvalue<-c(0.00,  0.00,  0.00, -0.01,  0.00,  0.01,  0.05,  0.04,  0.07,  0.06)
N<-c(3,3,2,5,7,3,2,4,5,1)
Data_gg<-cbind(subvalue,N)
Data_gg<-data.frame(Data_gg)
Data_gg


Je voudrais un résultat de ce type, avec le même nombre de lignes que mon dataframe d'origine, la répétition de mes valeurs et des NA là où je n'ai rien :
> result
[,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,] 0.00 0.00 0.00 NA NA NA NA
[2,] 0.00 0.00 0.00 NA NA NA NA
[3,] 0.00 0.00 NA NA NA NA NA
[4,] -0.01 -0.01 -0.01 -0.01 -0.01 NA NA
[5,] 0.00 0.00 0.00 0.00 0.00 0 0
[6,] 0.01 0.01 0.01 NA NA NA NA
[7,] 0.05 0.05 NA NA NA NA NA
[8,] 0.04 0.04 0.04 0.04 NA NA NA
[9,] 0.07 0.07 0.07 0.07 0.07 NA NA
[10,] 0.06 NA NA NA NA NA NA


J'ai testé différentes combinaisons avec matrix, apply et rep mais je ne trouve pas la bonne

Code : Tout sélectionner

rep(Data_gg$subvalue,Data_gg$N)

me donne les bonnes valeurs bout à bout

Code : Tout sélectionner

matrix(rep(Data_gg$subvalue,Data_gg$N),ncol=max(N))

me donne complètement autre chose

Auriez vous une idée svp?

Merci d'avance
Guillaume

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

Re: remplir une matrice

Messagepar Mickael Canouil » 26 Avr 2019, 08:24

Bonjour,

La réponse (du moins une partie):

Code : Tout sélectionner

?rep

Code : Tout sélectionner

?mapply


EDIT:
subvalue<-c(0.00, 0.00, 0.00, -0.01, 0.00, 0.01, 0.05, 0.04, 0.07, 0.06)
N<-c(3,3,2,5,7,3,2,4,5,1)
Data_gg<-cbind(subvalue,N)
Data_gg<-data.frame(Data_gg)
Data_gg

Code : Tout sélectionner

Data_gg <- data.frame(
  subvalue = c(0.00,  0.00,  0.00, -0.01,  0.00,  0.01,  0.05,  0.04,  0.07,  0.06),
  N = c(3, 3, 2, 5, 7, 3, 2, 4, 5, 1)
)


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

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

Re: remplir une matrice

Messagepar Logez Maxime » 26 Avr 2019, 09:29

Bonjour,

Code : Tout sélectionner

t(mapply(function(x, y) rep(c(x, NA), c(y, mN-y)), subvalue, N))
Cordialement,
Maxime

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

Re: remplir une matrice

Messagepar Mickael Canouil » 26 Avr 2019, 09:55

Bon... Maxime a donné une réponse.

Par contre, je suggère une petite modification, pour ne pas avoir de variable globale dans la fonction (i., e., "mN" faute de frappe pour "N").
Tous les objets/variables utilisées dans une fonction devraient systématiquement se trouver dans les arguments de la dite fonction (anonyme ou pas).

Code : Tout sélectionner

Data_gg <- data.frame(
  subvalue = c(0.00,  0.00,  0.00, -0.01,  0.00,  0.01,  0.05,  0.04,  0.07,  0.06),
  N = c(3, 3, 2, 5, 7, 3, 2, 4, 5, 1)
)

Code : Tout sélectionner

attach(Data_gg)

t(mapply(
  FUN = function(x, y, n) {
    rep(c(x, NA), c(y, n - y))
  },
  x = subvalue,
  y = N,
  n = max(N)
))
#>        [,1]  [,2]  [,3]  [,4]  [,5] [,6] [,7]
#>  [1,]  0.00  0.00  0.00    NA    NA   NA   NA
#>  [2,]  0.00  0.00  0.00    NA    NA   NA   NA
#>  [3,]  0.00  0.00    NA    NA    NA   NA   NA
#>  [4,] -0.01 -0.01 -0.01 -0.01 -0.01   NA   NA
#>  [5,]  0.00  0.00  0.00  0.00  0.00    0    0
#>  [6,]  0.01  0.01  0.01    NA    NA   NA   NA
#>  [7,]  0.05  0.05    NA    NA    NA   NA   NA
#>  [8,]  0.04  0.04  0.04  0.04    NA   NA   NA
#>  [9,]  0.07  0.07  0.07  0.07  0.07   NA   NA
#> [10,]  0.06    NA    NA    NA    NA   NA   NA

detach(Data_gg)


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

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

Re: remplir une matrice

Messagepar Logez Maxime » 26 Avr 2019, 12:27

Arff je suis allé trop vite, mN était le nombre max de N.

Code : Tout sélectionner

mN <- max(N)

Je ne vois pas trop le problème de la variable globale mais pourquoi pas, soit on la passe implicitement soit directement comme argument, le résultat ici étant le même.
Moi c'est plus les "attach" "detach" dont je me 'méfie', je préfère utiliser with.

Code : Tout sélectionner

with(Data_gg, t(mapply(
   FUN = function(x, y, n) {
     rep(c(x, NA), c(y, n - y))
   },
   x = subvalue,
   y = N,
   n = max(N)
 )))
Cordialement,
Maxime

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

Re: remplir une matrice

Messagepar Mickael Canouil » 26 Avr 2019, 15:07

j'ai fait le attach/detach pour aller plus vite ici, mais il vaut mieux éviter. (je n'utilise personnellement ni with, ni attach/detach).

Une variable globale est un risque de fonctionnement "anormale" et "indétectable" d'une fonction.

Concrètement, avec une variable globale dans une fonction, le résultat est "imprévisible", alors qu'avec un argument il ne l'est pas.
De plus, l'erreur est explicite.

Exemple tout bête:
Une fonction avec variable globale (tmp change, mais l'appel à f reste exactement le même avec un résultat différent)

Code : Tout sélectionner

f <- function(x) x + tmp

f(1)
#> Error in f(1): object 'tmp' not found

tmp <- 1
f(1)
#> [1] 2

tmp <- 2
f(1)
#> [1] 3


La même fonction sans variable globale

Code : Tout sélectionner

g <- function(x, tmp) x + tmp

g(1)
#> Error in g(1): argument "tmp" is missing, with no default

g(1, 1)
#> [1] 2

g(1, 2)
#> [1] 3


Pour du débogage et le partage du code, l'absence de variable globale est préférable (d'ailleurs les variables globales aboutissent à des "NOTE" dans les vérifications du CRAN pour les packages).
Mickaël
mickael.canouil.fr | rlille.fr

Guillaume Dramais
Messages : 39
Enregistré le : 25 Sep 2018, 00:04

[RESOLU] Re: remplir une matrice

Messagepar Guillaume Dramais » 26 Avr 2019, 15:54

Merci beaucoup de vos réponses et de vos conseils.

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

Re: remplir une matrice

Messagepar Logez Maxime » 26 Avr 2019, 22:13

Mickael Canouil a écrit :Une variable globale est un risque de fonctionnement "anormale" et "indétectable" d'une fonction.

Concrètement, avec une variable globale dans une fonction, le résultat est "imprévisible", alors qu'avec un argument il ne l'est pas.
De plus, l'erreur est explicite.

Exemple tout bête:
Une fonction avec variable globale (tmp change, mais l'appel à f reste exactement le même avec un résultat différent)

Pour du débogage et le partage du code, l'absence de variable globale est préférable (d'ailleurs les variables globales aboutissent à des "NOTE" dans les vérifications du CRAN pour les packages).
Je partage quasiment toutes ces remarques qui font partie des bonnes pratiques à adopter quand on fait de la programmation. Pour autant comme tu l'as fait remarqué par exemple avec l'utilisation de attach et detach il s'agissait ici de donner un code qui donne rapidement satisfaction par rapport à une question relativement simple et non un code développé pour le CRAN :-)
De même que si on oublie un argument d'une fonction il est relativement simple de débugger le problème le message d'erreur de R te ramenant très vitre à ton inattention, alors que si tu te trompes de valeurs de tmp il est plus dur de voir d'où vient le problème. A priori si on se plante sur le calcul du maximum, que ce soit pour créer mN ou pour passer cette valeur en argument d'une fonction, on aura un résultat non souhaité.

Dans les bonnes pratiques on peut ajouter que si l'opération devait être répétée plusieurs fois, on serait plus parti vers l'élaboration d'une fonction qui permette de faire cette manipulation de données sur tout un tas de data.frame par exemple, ou qui pourrait resservir au besoin. Dans ce cas là définir mN en local dans le corps de la fonction et s'en servir dans le mapply sans pour autant qu'il soit dans les arguments de la fonction appliquée (faire la même chose que là mais dans le corps d'une fonction) ne pose aucun souci et est une façon de faire très pratique qui joue sur l'imbrication des environnements. La seule différence c'est qu'ici l'environnement de plus haut niveau est l'environnement global et que donc on conservera mN comme objet par la suite alors que dans l'autre cas cet objet restera en local.

Cordialement,
Maxime


Retourner vers « Questions en cours »

Qui est en ligne

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