Simplifier une création de variable avec apply?

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

Tai PHAM
Messages : 47
Enregistré le : 18 Jan 2011, 11:58

Simplifier une création de variable avec apply?

Messagepar Tai PHAM » 06 Sep 2018, 16:06

Bonjour à tous,

je travaille sur une base de données où les sujets sont suivis quotidiennement avec les même mesures répétées jusqu'à un maximum de J50.
Je voudrais créer des variables dépendantes de ce ce qui se passe les jours précédents mais ne sais pas comment le faire simplement avec un script "général" où je pourrais spécifier "J moins 1" sans avoir à strictement nommer la variable.

Je vous donne un exemple pour clarifier ma demande.
Soit variable "Fièvre": fievre_J1; fievre_J2 [...] fievre_J50

Si je veux créer une variable "pas de fièvre pendant 3 jours", pour le moment je fais

Code : Tout sélectionner

db$apyrexie_72h<-as.factor(ifelse(db$fievre_J1=="0"&db$fievre_J2=="0"1db$fievre_J3=="0", "1",
ifelse(db$fievre_J2=="0"&db$fievre_J3=="0"1db$fievre_J4=="0", "1",
ifelse(db$fievre_J3=="0"&db$fievre_J4=="0"1db$fievre_J5=="0", "1"
[...]
ifelse(db$fievre_J48=="0"&db$fievre_J49=="0"1db$fievre_J50=="0", "1",,"0")))))))))))))))))))))))))))))))))))))))[...]


C'est faisable mais fastidieux avec un risque important de coquilles.
J'imagine qu'il y a un moyen plus simple d'obtenir le même résultat.

Question subsidiaire, est-il aussi possible de créer non pas une variable factorielle mais numérique identifiant le jour à laquelle on obtient la condition voulue? Ce qui donnerait avec mon script

Code : Tout sélectionner

db$premier_jour_apyrexie_72h<-as.numerical(ifelse(db$fievre_J1=="0"&db$fievre_J2=="0"1db$fievre_J3=="0", 1,
ifelse(db$fievre_J2=="0"&db$fievre_J3=="0"1db$fievre_J4=="0", 2,
ifelse(db$fievre_J3=="0"&db$fievre_J4=="0"1db$fievre_J5=="0", 3
[...]
ifelse(db$fievre_J48=="0"&db$fievre_J49=="0"1db$fievre_J50=="0", 48,NA)))))))))))))))))))))))))))))))))))))))[...]


Merci beaucoup de votre aide,

Tài

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

Re: Simplifier une création de variable avec apply?

Messagepar Logez Maxime » 06 Sep 2018, 18:43

Bonjour,

une possibilité avec la fonction apply :

Code : Tout sélectionner

f1 <- function(x)  {
  rle1 <- rle(x)
  rle1 <- rle1$length[rle1$val<0.5]
  if (any(rle1 == 3)) "1" else "0"
  }
 # la condition peut-être changée par > 2.5 par exemple si au moins 3 jours et non pas 3 jours stricts
apply(db, 1, f1)

Cordialement,
Maxime

Tai PHAM
Messages : 47
Enregistré le : 18 Jan 2011, 11:58

Re: Simplifier une création de variable avec apply?

Messagepar Tai PHAM » 07 Sep 2018, 13:35

Merci beaucoup Maxime,

J'ai du remplacer

Code : Tout sélectionner

if (any(rle1 == 3)) "1" else "0"

par

Code : Tout sélectionner

ifelse (any(rle1 == 3), "1", "0")


Et cela fonctionne parfaitement pour la plupart des cas, il reste cependant quelques "NA" que je n'explique pas mais je vais regarder le détail.
J'ai l'impression que pour utiliser cette solution, il faut que je sépare ma base de données en plusieurs parties de bases contenant seulement mes variables d'intérêt et sur lesquelles j'appliquerais la fonction pour créer mes nouvelles variables avant de merger les différentes bases.

Ma question était plus générale car j'ai besoin de construire des variables avec plusieurs conditions sur les jours précédents et je souhaiterais pourvoir écrire un script dans l'esprit suivant en appelant le jour d'intérêt "Jx", les jours précédents "Jx-1", "Jx-2"...

Code : Tout sélectionner

db$new_variable_Jx<-ifelse(db$var1_Jx-1=="1" & db$var2_Jx-1=="0" & db$var3_Jx-2=="1","1","0")


J'espère que mon exemple est clair.

Merci encore de votre aide,

Tài

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

Re: Simplifier une création de variable avec apply?

Messagepar Logez Maxime » 07 Sep 2018, 13:43

Bonjour,

la solution que je t'ai donné ne fonctionne que pour un tableau qui ne contiendrait que les colonnes de jours qui t'intéressent.
Il te faut donc faire une commande pour ne récupérer que les colonnes en sachant à quel jour tu t'arrêtes (ex. J50) et de combien tu recules (-1, -3, -10 etc.)

Code : Tout sélectionner

n <- 10
x <- 50
cols <- sprintf("var1_J%s", x:(x-n))
apply(db[,cols], 1, f1)

Après je ne sais pas pourquoi tu as eu besoin de transformer la commande if (...) "1" else "0" par un ifelse, normalement il n'y a pas de raison. En plus ifelse est plu lente comme instruction.

Cordialement,
Maxime

Tai PHAM
Messages : 47
Enregistré le : 18 Jan 2011, 11:58

Re: Simplifier une création de variable avec apply?

Messagepar Tai PHAM » 07 Sep 2018, 14:09

Merci beaucoup pour ta réponse.
Je vais essayer de m'en sortir avec une combinaison des solutions que tu m'as proposées.

Amicalement,

Tài


Retourner vers « Questions en cours »

Qui est en ligne

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