2
votes

recode dans dplyr donnant une erreur: l'argument 2 doit être nommé, pas sans nom

J'ai un dataframe "employé" comme celui-ci:

Error: Argument 2 must be named, not unnamed

Je souhaite maintenant transformer ce dataframe de manière à ce que Dept_Id ait des noms de département au lieu de Dept_Id.

J'essaie d'utiliser recode de dplyr pour cela, puisque ma logique de transformation vient d'un csv, je devrais utiliser une variable à la place de la logique de transformation. p>

J'ai utilisé read.csv pour obtenir mon dataframe df où se trouve ma logique ( 1 = HR, 2 = IT et ainsi de suite), puis l'introduire une liste:

employee$Dept_Id <- recode(employee$Dept_Id,myList)

Pour obtenir la connexion à la transformation depuis df

myList <- as.character(df[1,3])

Remplacez maintenant le données dans l'employé selon la logique

df:

Source,Target,Transformation
Employee,Emp,"1=HR,2=Sales,3=Finance,4=IT"

Sur cette ligne, il me donne:

Emp_Id,Name,Dept_Id
20203,Sam,1
20301,Rodd,2
30321,Mike,3
40403,Derik,4


1 commentaires

@Ronak a modifié la question pour la même chose.


3 Réponses :


4
votes

Il existe plusieurs façons de procéder. Une solution est la suivante:

Méthode 1:

df <- fread("
Emp_Id  Name Dept_Id
20203   Sam  1
20301   Rodd 2            
")

name <- c("1" = "HR", "2"="IT")

Méthode 2:

codes <- list("1" = "HR", "2" = "IT")

df %>% 
    mutate(d2 = recode(Dept_Id, !!!codes))

Méthode 3:

df <- df %>% 
    mutate(Dept_Id_2 = case_when(
        Dept_Id == 1 ~ 'HR',
        Dept_Id == 2 ~ 'IT'
    ))

Configuration

df$Dept_Id <-  name[match(df$Dept_Id, names(name))]

    Emp_Id Name Dept_Id
1:  20203  Sam      HR
2:  20301 Rodd      IT


5 commentaires

Merci @YOHO va les essayer et vous mettre à jour. Bravo et bonne année!


J'ai essayé votre réponse, mais j'ai des problèmes pour obtenir le nom selon votre configuration car la condition que vous avez utilisée dans le nom <- c (....) provient d'une autre cellule CSV dans mon cas et il laisse tomber les guillemets lorsque lire les données depuis csv


Vous pouvez utiliser la table lookup de la réponse de ronak ci-dessus, et convertir la table en vecteur name en utilisant: name <- lookup $ X2; noms (nom) <- lookup $ X1


vous pouvez créer des codes en utilisant: codes = setNames (as.list (lookup $ X2), lookup $ X1)


Excellentes réponses, @YOLO. Pourriez-vous expliquer ce que fait le triple point d'exclamation !!! ??? :) Je n'ai pas trouvé de réponses évidentes sur Google



1
votes

Votre dataframe df a une structure différente qui rend difficile l'application directe des fonctions. Nous devons le nettoyer et l'amener dans un meilleur format afin qu'il soit facile d'interroger dessus.

Une façon de faire est de diviser les données sur , et = pour créer un nouveau dataframe ( lookup ) avec l'ID de service et Nom.

employee$Dept_Name <- lookup$X2[match(employee$Dept_Id, lookup$X1)]

employee
#  Emp_Id  Name Dept_Id Dept_Name
#1  20203   Sam       1        HR
#2  20301  Rodd       2     Sales
#3  30321  Mike       3   Finance
#4  40403 Derik       4        IT

Une fois que nous avons recherche , il est facile de faire correspondre par ID et obtenir le nom correspondant.

lookup <- data.frame(t(sapply(strsplit(as.character(df[1,3]), ",")[[1]],
                        function(x) strsplit(x, "=")[[1]])), row.names = NULL)

lookup
#  X1      X2
#1  1      HR
#2  2   Sales
#3  3 Finance
#4  4      IT


4 commentaires

Parfait! Merci @Ronak Shah


Si Dept_Id provient d'une variable comme: col <- input_data [1,2] lookup $ X2 [match (employee $ col, lookup $ X1)] Erreur: Erreur dans -lookup $ X2 [match (employee $ col, lookup $ X1)]: Erreur: argument non valide pour l'opérateur unaire, que faire?


@Deep Cela dépend de l'apparence de input_data [1,2] . Le but final est de créer un dataframe qui ressemble à lookup où une colonne a Dept_Id et l'autre a Dept_Name .


Nevermind..il y avait un problème avec l'espace lors de l'attribution de la valeur avec <-, fonctionnant maintenant.



0
votes

Une autre manière Si vous ne souhaitez pas modifier votre base de données existante et que la liste des services n'est pas trop grande.

Hypothèse: il n'y a aucune donnée manquante dans votre base de données "employés". si des données manquantes sont disponibles, il faut ajouter un niveau de condition supplémentaire.

Sinon, c'est le moyen simple d'appliquer votre logique, je l'ai mentionné dans le code ci-dessous

New_DF = ifelse(employee$Dept_Id == 1,"HR",ifelse(employee$Dept_Id == 2,"Sales",ifelse(employee$Dept_Id == 3,"Finance","IT")))
New_DF = cbind(employee,New_DF)


0 commentaires