Dictionnaire de style de remplacer plusieurs éléments
J'ai un gros volumes de données.trame de données de caractère que je veux convertir basé sur ce qui est communément appelé un dictionnaire dans d'autres langues.
Actuellement, je suis aller à ce sujet comme suit:
foo <- data.frame(snp1 = c("AA", "AG", "AA", "AA"), snp2 = c("AA", "AT", "AG", "AA"), snp3 = c(NA, "GG", "GG", "GC"), stringsAsFactors=FALSE)
foo <- replace(foo, foo == "AA", "0101")
foo <- replace(foo, foo == "AC", "0102")
foo <- replace(foo, foo == "AG", "0103")
Cela fonctionne bien, mais il n'est évidemment pas jolie et semble idiot de répéter le replace
déclaration chaque fois que je veux remplacer un élément dans les données.cadre.
Est-il une meilleure façon de le faire depuis que j'ai un dictionnaire d'environ 25 paires clé/valeur?
- Est votre dictionnaire de R liste?
- Pas actuellement, mais il serait facile d'en faire un.
- Peut-être que ce sont les questions qui pourraient vous être utile: de Cas d'Équivalent, Comment ajouter une colonne dans une
data.frame
, nettoyage des Données dans des feuilles de calcul Excel.
Vous devez vous connecter pour publier un commentaire.
en supposant que
map
couvre tous les cas defoo
. Cela permettrait de se sentir moins comme un "hack" et être plus efficace dans le temps et l'espace sifoo
ont été d'une matrice (de caractères()), puisDe la matrice et de la trame de données de variantes aller à l'encontre de R 2^31-1 de limite de taille de vecteur quand il y a des millions de Snp et des milliers d'échantillons.
Si vous êtes ouvert à l'aide de paquets,
plyr
est très populaire et a portée de main ce mapvalues() fonction qui va faire exactement ce que vous cherchez:Noter que cela fonctionne pour les types de données de toutes sortes, pas seulement des chaînes de caractères.
x
doit être atomique vecteur. Ceci est également documentée dans?mapvalues
.Ici est une solution rapide
*apply
fonctions ne sont PAS les mêmes que vectorisé.Voici quelque chose de simple qui fera le travail:
lapply
affichera une liste, dans ce cas, nous ne se soucient réellement. Vous pouvez affecter le résultat de quelque chose si vous voulez, et puis il suffit de le jeter. Je suis une itération sur les indices ici, mais vous pouvez tout aussi facilement placer la clé/vals-les-bains dans une liste eux-mêmes et itérer sur eux directement. Notez l'utilisation de la cession globale avec<<-
.J'ai bricolé un moyen de le faire avec
mapply
mais ma première tentative n'a pas fonctionné, donc je suis passé. Je soupçonne une solution avecmapply
est possible, si.<<-
.<<-
peut être risqué, mais il n'est pas intrinsèquement mauvais.Note cette réponse qui a commencé comme une tentative pour résoudre le problème bien plus simple posté dans Comment remplacer toutes les valeurs dans le bloc de données avec un vecteur de valeurs?. Malheureusement, cette question a été fermé comme un double de la question. Donc, je vais essayer de proposer une solution basée sur le remplacement des niveaux des facteurs pour les deux cas, ici.
Dans le cas où il n'est qu'un vecteur (ou une trame de données de la colonne)
dont les valeurs doivent être remplacés et il n'y a pas d'objections à l'utilisation du facteur, nous pouvons forcer le vecteur de facteur et de modifier les niveaux de facteurs comme l'exige:
À l'aide de la
forcats
le paquet de ce qui peut être fait dans un one-liner:En cas tous valeurs de plusieurs colonnes d'un bloc de données doivent être remplacés, l'approche peut être étendue.
Noter que
level_vec
etreplacement_vec
doivent avoir des longueurs égales.Plus important encore,
level_vec
devrait être complète , c'est à dire, inclure toutes les valeurs possibles dans les colonnes de l'original de la trame de données. (Utiliserunique(sort(unlist(foo)))
à vérifier). Sinon, toutes les valeurs manquantes seront contraints de<NA>
. Notez que c'est aussi une exigence pour Martin Morgans réponse.Donc, si il n'y a que peu de valeurs différentes pour être remplacé, vous serez probablement mieux avec l'une des autres réponses, par exemple, Ramnath de l'.
Utilisé @Ramnath la réponse ci-dessus, mais le fait de lire (ce qui doit être remplacé et ce sera remplacé par) à partir d'un fichier et d'utiliser gsub plutôt que de le remplacer.
hgword.txt contient les éléments suivants, séparés par des tabulations
Depuis qu'il a été quelques années depuis la dernière réponse, et une nouvelle question s'est posée ce soir sur ce sujet et un modérateur fermé, je vais l'ajouter ici. L'affiche a un grand bloc de données contenant 0, 1, et 2, et veut les modifier à AA, AB et BB respectivement.
Utilisation
plyr
:Créer une fonction sur le bloc de données à l'aide de
revalue
pour remplacer plusieurs termes:Nous pouvons également utiliser
dplyr::case_when
Il vérifie l'état et la remplace par la valeur correspondante si la condition est
TRUE
. On peut ajouter des conditions supplémentaires si nécessaire et avecTRUE ~ .
nous conservons les valeurs qu'elle est si aucun de l'état est mis en correspondance. Si nous voulons changer àNA
au lieu de cela, nous pouvons supprimer la dernière ligne.Cela va changer les valeurs de
NA
si aucun de la condition ci-dessus est satisfaite.Une autre option à l'aide seulement de la base de R est de créer un
lookup
dataframe avec les anciennes et nouvelles valeurs,unlist
le dataframe,match
avec les valeurs anciennes, obtenir les nouvelles valeurs et de les remplacer.À l'aide de dplyr::recode: