J'ai un df où value
indique l'état d'un drug
:
drug value 1 a fda 2 a fda 3 a fda 4 d case 5 d case
Donc pour les médicaments, je veux remplacer tout répéter le médicament
en fonction de l'ordre de priorité suivant pour valeur
:
fda > trial > case > pre
Par exemple, si le médicament d est «cas» ainsi que «pré», toute incidence de d sera reclassée comme «cas». La table finale devrait ressembler à ceci.
g1 = data.frame ( drug = c('a','a','a','d','d'), value = c('fda','trial','case','case','pre') ) drug value 1 a fda 2 a trial 3 a case 4 d case 5 d pre
Comment faire cela sans avoir à parcourir chaque médicament et à déterminer la priorité avant de le remplacer?
3 Réponses :
Mise à jour à l'aide d'un vecteur
de carte, ce que je faisais, car je ne veux pas changer le type de colonnes.
mapvect=c(1,2,3,4) names(mapvect)=c('pre','case','trial','fda') g1$helpkey=mapvect[g1$value] g1 %>% group_by(drug) %>% arrange(value)%>% dplyr::mutate(value=value[helpkey==max(helpkey)]) # A tibble: 5 x 3 # Groups: drug [2] drug value helpkey <chr> <chr> <dbl> 1 a fda 2 2 d case 2 3 a fda 4 4 d case 1 5 a fda 3
Ce n'est pas aussi bon que la réponse de @ thelatemail, cela crée un facteur non ordonné et repose sur l'ordre souhaité des valeurs se produisant dans l'ordre dans le dataframe; si cela ne se produit pas, il se brise. Une meilleure approche est classée par catégorie avec min
.
Vous n'avez pas besoin de créer une colonne d'aide, ne pouvez-vous pas simplement opérer directement sur min (valeur)
? Quoi qu'il en soit, si vous le créez, vous souhaitez supprimer la colonne d'aide %>% select (-helpkey)
Similaire à la réponse de @ Wen-Ben, avec les fonctions base
, vous pouvez également faire:
g1$value <- factor(g1$value, levels = c("fda", "trial", "case", "pre")) g1 <- g1[order(g1$value),] g1$value <- g1[match(g1$drug, g1$drug), "value"]
Comme il s'agit d'une variable ordinale, vous pouvez faire de g1 $ value
un facteur ordonné
comme classe
correspondante. Ensuite, vous pouvez utiliser des fonctions telles que min
et max
comme vous le feriez avec un numérique:
g2 = data.frame ( drug = c( "a","a","a","d","d","e","e","e"), value = c("fda","trial","case","case","pre","pre","fda","case") ) # drug value #1 a fda #2 a trial #3 a case #4 d case #5 d pre #6 e pre #7 e fda #8 e case g2 %>% mutate(value = ordered(value, levels = c("fda", "trial", "case", "pre"))) %>% group_by(drug) %>% mutate(value = min(value)) ## A tibble: 8 x 2 ## Groups: drug [3] # drug value # <fct> <ord> #1 a fda #2 a fda #3 a fda #4 d case #5 d case #6 e fda #7 e fda #8 e fda
Ou dans dplyr speak:
g1 %>% mutate(value = ordered(value, levels = c("fda", "trial", "case", "pre"))) %>% group_by(drug) %>% mutate(value = min(value))
L'ordre dans l'ensemble de données et la plage de valeurs présentes dans tout groupe médicament
ne devraient pas affecter ce résultat:
g1$value <- ordered(g1$value, levels = c("fda", "trial", "case", "pre")) g1$value #[1] fda trial case case pre #Levels: fda < trial < case < pre g1$value <- ave(g1$value, g1$drug, FUN=min) g1 # drug value #1 a fda #2 a fda #3 a fda #4 d case #5 d case
c'est super et ça marche bien. J'aime particulièrement le premier exemple car il ne nécessite que la base R et cela a beaucoup de sens. Répondez ci-dessus à propos des dups, bien qu'il y ait beaucoup de questions similaires, je ne peux pas en trouver une qui aurait pu répondre à ce dont j'avais besoin.
Utilisez
dplyr :: mutate (value = case_when (...))
; c'est une copie de beaucoup de questions existantes.Double possible de dplyr mutate avec des valeurs conditionnelles
@smci - à mon humble avis, ce n'est pas une dupe. Le traiter comme une variable ordinale semble plus simple que d'écrire plusieurs instructions case when.
@thelatemail: oui c'est certainement une dupe de beaucoup de questions existantes; il y a 10 686 appels (!) sur
dplyr mutate
seul et 469 appels surdplyr mutate / case_when
ouifelse
a>. Je les ai parcourus depuis un moment, la seule question est de savoir quelle est la meilleure cible de dupe. Pouvez-vous en choisir un?@smci - aucune des 3 réponses ici n'a utilisé case_when ou ifelse, donc je pense que la logique n'est pas une bonne correspondance avec ce qui consiste essentiellement à prendre un minimum par groupe une fois que la variable ordonnée est définie. Il pourrait y avoir une correspondance, mais je n'ai pas beaucoup de chance de trouver quelque chose de très bon - stackoverflow.com/questions/39403317/… a > est une idée similaire mais pas tout à fait.
Il serait utile qu'Ahdee indique si chaque valeur de
fda, trial, case, pre
est garantie d'exister, et dans cet ordre, pour chaquedrogue
b >. Ce n'est pas indiqué explicitement, mais les réponses semblent reposer sur cela. (Ouais @thelatemail si c'est une contrainte explicite ça change les réponses). Et si un médicament avait une entrée pourfda
mais pas pourtrial
, par quoi devrions-nous alors remplacercase
? Ou le code peut-il supposer que cela ne peut pas arriver?@smci - si c'est un facteur ordonné selon ma réponse, cela n'a pas d'importance. La valeur minimale sera la première dans l'ordre spécifié. Voir la modification de ma réponse.
@thelatemail: il incombe à l'OP d'énoncer clairement les contraintes de la question. Votre réponse est assez soignée, mais si quelqu'un convertit en chaîne / facteur non ordonné / ordinal puis exporte (par exemple en tant que csv) et relit, cela pourrait être fragile. Que se passe-t-il si un statut d'essai nouveau ou invisible est rencontré? etc.
@smci - s'il y a un nouveau statut d'essai de drogue invisible, j'imagine que tout code, qu'il soit basé sur des facteurs ou basé sur le cas / quand, devra changer pour en tenir compte.
HI remercie tout le monde pour votre aide dans ce domaine. J'ai essayé de parcourir les réponses précédentes, mais je n'ai pas pu en trouver une capable de résoudre mon problème jusqu'à présent. Pour répondre aux questions ci-dessus, il n'est pas garanti que les valeurs existent, mais comme indiqué par @smci, le facteur ordonné fonctionne indépendamment de la valeur manquante.
(Il y avait cette question , sauf en utilisant
summary
sur le facteur ordonné au lieu demutate
, et il s'agissait plus d'un ancien bogue dans dplyr 0.5.0, et il n'a pas de réponse, alors ne l'utilisez pas ).Ok, j'ai rétracté mon vote close-as-dupe: il est préférable de le gérer avec un classement catégorique et
min ()
. Le titre ne nous dit sérieusement pas de quoi il s'agit, au sens du code ...@smci merci pour le suivi et les réponses ci-dessous ont énormément aidé. Vous ne savez pas comment modifier le titre? Aucune suggestion?
@Ahdee: bien sûr. si vous souhaitez modifier le titre pour être plus clair, veuillez le faire; seul l'OP est censé le faire une fois qu'une question a des réponses. Cela dépend de la manière dont vous souhaitez exposer votre problème; le titre actuel utilise un langage très vague; votre code implique également que
drogue
etvaleur
sont des chaînes, mais plus tard, les répondants en déduisent qu'il aurait été préférable de déclarer lavaleur
en tant que catégoriel ordonné, avec l'ordre de priorité spécifique que vous avez donné (doncmin ()
fonctionne comme prévu). Il est peut-être préférable de demander "Comment représenter au mieux la colonne de dataframe lorsque je souhaite appliquer l'ordre de priorité à ses valeurs?"