Je suis un programmeur R très novice et j'essaie de convertir l'ancien code SAS en R. Je dois remplacer les valeurs en fonction d'une condition, et si la condition est fausse, laissez-les seules. J'ai googlé cela et essayé plusieurs des solutions affichées, mais en vain. La raison pour laquelle je fais cela est de classer la première instance d'un événement (dans ce cas, les médecins rédigent une ordonnance). si le premier mois où ils ont écrit une ordonnance était le mois de mai de l'année dernière, leur mois de début (rédacteur) était de 5. Si c'était en juin, puis de 6 ans, etc. débutant (newwriter) si une ordonnance antérieure est trouvée. Si aucune ordonnance antérieure n'est trouvée, je veux laisser le numéro seul. C'est le code que j'utilise:
newwriters$newwriter=ifelse(newwriters$MTRx_06_30_2017>0,18,NULL)
newwriters$newwriter=ifelse(newwriters$MTRx_05_31_2017>0,17,NULL)
newwriters$newwriter=ifelse(newwriters$MTRx_04_30_2017>0,16,NULL)
newwriters$newwriter=ifelse(newwriters$MTRx_03_31_2017>0,15,NULL)
newwriters$newwriter=ifelse(newwriters$MTRx_02_28_2017>0,14,NULL)
newwriters$newwriter=ifelse(newwriters$MTRx_01_31_2017>0,13,NULL)
newwriters$newwriter=ifelse(newwriters$MTRx_12_31_2016>0,12,NULL)
newwriters$newwriter=ifelse(newwriters$MTRx_11_30_2016>0,11,NULL)
newwriters$newwriter=ifelse(newwriters$MTRx_10_31_2016>0,10,NULL)
Le problème est qu’il continue de changer les valeurs les plus élevées en 0 s’il ne trouve pas de prescription ce mois-ci. Je veux juste laisser les valeurs seules. J'ai également essayé toutes les solutions suivantes sans succès:
newwriters$newwriter=ifelse(newwriters$MTRx_06_30_2017>0,18,newwriters$newwriter)
newwriters$newwriter=ifelse(newwriters$MTRx_06_30_2017>0,18,newwriters[,16])
newwriters$newwriter=ifelse(newwriters$MTRx_06_30_2017>0,18,)
Comme je l'ai mentionné, je suis novice en écriture de code R. Je suis sûr qu'il existe un moyen meilleur/plus rapide/plus efficace de le faire, mais je ne sais pas quoi essayer d'autre. Merci d'avance pour votre aide!
Si vous souhaitez modifier conditionnellement une colonne (ou un vecteur) et laisser les entrées inchangées lorsque la condition n'est pas remplie, vous pouvez probablement aussi vous passer de ifelse
.
Considérons les deux vecteurs suivants:
a = c(1,2,3,4,5)
b = c(1,1,1,1,1)
Maintenant, supposons que nous voulions remplacer les valeurs dans b
par 2
, si la valeur dans a
est supérieure à 3
. Voici deux façons de réaliser ce que vous voulez:
b[a>2] = 2
b = ifelse(a>3,2,b)
Ils aboutiront tous deux à b
étant 1 1 2 2 2
. Cependant, remplaçons maintenant l'une des valeurs dans a
, par NA
, disons;
a = c(1,2,NA,4,5)
Maintenant, comparez les résultats des deux extraits suivants:
b = c(1,1,1,1,1)
b[a>2] = 2
# 1 1 1 2 2
et
b = c(1,1,1,1,1)
b = ifelse(a>3,2,b)
# 1 1 NA 2 2
La raison intuitive en est que NA>3
ne renvoie pas TRUE
ou FALSE
, mais NA
, donc ifelse
ne sait pas lequel des deux champs doit être renvoyé. Lorsque b[a>2]
est utilisé, nous ne remplaçons que les valeurs où a>2
est TRUE
, et puisque NA
n'est pas TRUE
, la valeur de la troisième entrée n'est tout simplement pas modifiée.
Donc, dans votre cas particulier,
writers$newwriter=ifelse(newwriters$MTRx_06_30_2017>0,18,newwriters$newwriter)
ne fonctionne probablement pas comme prévu car il y a des valeurs NULL ou NA dans ces colonnes. Si vous voulez utiliser ifelse
, vous pouvez faire quelque chose comme:
writers$newwriter=ifelse(newwriters$MTRx_06_30_2017>0 & !is.na(newwriters$MTRx_06_30_2017),18,newwriters$newwriter)
mais vous pourriez aussi envisager de faire
writers$newwriter[newwriters$MTRx_06_30_2017>0] = 18
J'espère que cela t'aides!
Mieux vaut utiliser if_else
du paquet dplyr . Il a un traitement explicite pour NA
s qui le rend plus robuste et il est aussi légèrement plus rapide.
Exemple rapide:
> library(tidyverse)
> iris2 = iris %>% as_data_frame()
>
> #add some NA's
> iris2$Sepal.Length[c(1, 5, 8)] = NA
>
> #print
> iris2
# A tibble: 150 x 5
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
<dbl> <dbl> <dbl> <dbl> <fct>
1 NA 3.50 1.40 0.200 setosa
2 4.90 3.00 1.40 0.200 setosa
3 4.70 3.20 1.30 0.200 setosa
4 4.60 3.10 1.50 0.200 setosa
5 NA 3.60 1.40 0.200 setosa
6 5.40 3.90 1.70 0.400 setosa
7 4.60 3.40 1.40 0.300 setosa
8 NA 3.40 1.50 0.200 setosa
9 4.40 2.90 1.40 0.200 setosa
10 4.90 3.10 1.50 0.100 setosa
# ... with 140 more rows
>
> #conditionally change
> iris2$new_var = if_else(iris2$Sepal.Length > 5, true = 100, false = 0, missing = -100)
>
> iris2$new_var
[1] -100 0 0 0 -100 100 0 -100 0 0 100 0 0 0 100 100 100 100 100 100 100 100 0 100 0 0 0
[28] 100 100 0 0 100 100 100 0 0 100 0 0 100 0 0 0 0 100 0 100 0 100 0 100 100 100 100
[55] 100 100 100 0 100 100 0 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100
[82] 100 100 100 100 100 100 100 100 100 100 100 100 0 100 100 100 100 100 100 100 100 100 100 100 100 0 100
[109] 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100
[136] 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100
Nous avons donc créé une nouvelle variable où les valeurs supérieures à 5 sont passées à 100, inférieures à 5 à 0 et NA
à -100.