recode in dplyr giving Error: Argument 2 must be named, not unnamed

Viewed 8767

I have a dataframe "employee" like this:

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

Now i want to transform this dataframe in a way that the Dept_Id have department names instead of Dept_Id.

I am trying to use recode from dplyrfor this, since my transformation logic comes from a csv, I would have to use a variable in place of transformation logic.

I used read.csv to get my dataframe df where my logic (1=HR,2=IT and so on) sits and then get it in a list:

df:

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

To get the transaformation login from df

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

Now replacing the data in employee as per the logic

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

On this line it is giving me:

Error: Argument 2 must be named, not unnamed
3 Answers

There are multiple ways to do this. One way is:

Method 1:

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

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

Method 2:

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

Method 3:

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

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

Setup

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

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

Your dataframe df has a different structure which makes it difficult to apply functions directly. We need to clean it and bring it in a better format so that it is easy to query on it.

One way to do that is to split the data on , and = to create a new dataframe (lookup) with department ID and Name.

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

Once we have lookup then it is easy to match by ID and get corresponding name.

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

Another way If you don't want to change your existing database and the department list is not too big.

Assumption: there is not any missing data in your "employee" database. if any missing data available then need to add one more level of condition.

ifelse is the simple way to apply your logic, I have mentioned that in below code

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)
Related