2
votes

I am performing Data Analysis and cleaning in R using tidyverse. I have a Data Frame with 23 columns containing values 'NO','STEADY','UP' and 'down'. I want to change all the values in these 23 columns to 0 in case of 'NO','STEADY' and 1 in other case.

What i did is, i created a list by name keys in which i have kept all my columns, After that i am using for loop, ifelse statements and mutate.

Please have a look at the code below

# Column names are kept in the list by name keys

keys = c('metformin', 'repaglinide', 'nateglinide', 'chlorpropamide', 'glimepiride', 
'glipizide', 'glyburide', 'pioglitazone', 'rosiglitazone', 'acarbose', 'miglitol', 
'insulin', 'glyburide-metformin', 'tolazamide', 'metformin-pioglitazone',
'metformin-rosiglitazone', 'glimepiride-pioglitazone', 'glipizide-metformin', 
'troglitazone', 'tolbutamide', 'acetohexamide')

After that, i used following code to get the desired result :

for (col in keys){
  Dataset = Dataset %>%
    mutate(col = ifelse(col %in% c('No','Steady'),0,1)) }

I was expecting that, it will do the changes that i require, but nothing happens after this. (NO ERROR MESSAGE AND NO DESIRED RESULT)

After that, i researched further and executed following code

for (col in keys){
 print(col)}

It gives me elements of list as characters like - "metformin"

So, i thought - may be this is the issue. Hence, i used the below code to caste the keys as symbols :

keys_new = sym(keys)

After that i again ran the same code:

for (col in keys_new){
   Dataset = Dataset %>%
     mutate(col = ifelse(col %in% c('No','Steady'),0,1))} 

It gives me following Error -

Error in match(x, table, nomatch = 0L) : 'match' requires vector arguments

After all this. I also tried to create a function to get the desired results, but that too didn't worked:

change = function(name){
   Dataset = Dataset %>%
      mutate(name = ifelse(name %in% c('No','Steady'),0,1),
      name = as.factor(name))
      return(Dataset)}

for (col in keys){
   change(col)}

This didn't perform any action. (NO ERROR MESSAGE AND NO DESIRED RESULT)

When keys_new is placed in this code:

for (col in keys_new){
   change(col)}

I got the same Error :

Error in match(x, table, nomatch = 0L) : 'match' requires vector arguments

PLEASE GUIDE

3

3 Answers

3
votes

There's a simpler way using mutate_at and case_when.

Dataset %>% mutate_at(keys, ~case_when(. %in% c("NO", "STEADY") ~ 0, TRUE ~ 1))

mutate_at will only mutate the columns specified in the keys variable. case_when then lets you replace one value by another by some condition.

3
votes

There's no need to loop or keep track of column names. You can use mutate_all -

Dataset %>% 
  mutate_all(~ifelse(. %in% c('No','Steady'), 0, 1))

Another way, thanks to Rui Barradas -

Dataset %>% 
  mutate_all(~as.integer(!. %in% c('No','Steady')))
2
votes

This answer for using mutate through forloop.

I don't have your data, so i tried to make my own data, i changed the keys into a tibble using enframe then spread it into columns and used the row number as a value for each column, then check if the value is higher than 10 or not.

To use the column name in mutate you have to use !! and := in the mutate function

df <- enframe(c('metformin', 'repaglinide', 'nateglinide', 'chlorpropamide', 'glimepiride', 
                 'glipizide', 'glyburide', 'pioglitazone', 'rosiglitazone', 'acarbose', 'miglitol', 
                 'insulin', 'glyburide-metformin', 'tolazamide', 'metformin-pioglitazone',
                 'metformin-rosiglitazone', 'glimepiride-pioglitazone', 'glipizide-metformin', 
                 'troglitazone', 'tolbutamide', 'acetohexamide')
) %>% spread(key = value,value = name)

keys = c('metformin', 'repaglinide', 'nateglinide', 'chlorpropamide', 'glimepiride', 
         'glipizide', 'glyburide', 'pioglitazone', 'rosiglitazone', 'acarbose', 'miglitol', 
         'insulin', 'glyburide-metformin', 'tolazamide', 'metformin-pioglitazone',
         'metformin-rosiglitazone', 'glimepiride-pioglitazone', 'glipizide-metformin', 
         'troglitazone', 'tolbutamide', 'acetohexamide')


for (col in keys){
        df = df %>%
                mutate(!!as.character(col) := ifelse( df[col] > 10,0,100) )
        }