4

I have been trying to write a function in R that can replace strings in particular column by numerals. Following is my example:

d <- data.frame(A = c("D",1,2,3,"D",1,2,"B","D",3,5),
                  B = c(7,8,9,4,5,8,9,1,6,7,8))
func <- function(dat,rep_val_col,rep_val_col_change,new_val)
{
  dat[dat[,rep_val_col] == rep_val_col_change[1],],rep_val_col] = new_val[1]
  dat[dat[,rep_val_col] == rep_val_col_change[2],],rep_val_col] = new_val[2]
}

func(d,"A",c("D","B"),new_val = c(9,10))

I want to replace "D" and "B" in column A by 9 and 10 respectively.

6 Answers 6

4
levels(d$A)[levels(d$A) %in% c("B", "D")] <- c(9, 10)
d$A <- as.numeric(as.character(d$A))
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. That worked I have modified it for function and it worked perfectly. code func <- function(dat,rep_val_col,rep_val_col_change,new_val) { levels(dat[,rep_val_col])[levels(dat[,rep_val_col]) %in% rep_val_col_change] <- new_val dat[,rep_val_col] <- as.numeric(as.character(dat[,rep_val_col])) return(dat) } func(d,"A",c("D","B"),new_val = c(9,10)) code
2

We can do this with tidyverse

library(dplyr)
d %>%
     mutate(A = case_when(A =="D" ~"9",
                          A=="B" ~ "10",
                         TRUE ~as.character(A)), 
           A = as.integer(A))    #    A B
#1   9 7
#2   1 8
#3   2 9
#4   3 4
#5   9 5
#6   1 8
#7   2 9
#8  10 1
#9   9 6
#10  3 7
#11  5 8

Comments

0

You can use nested ifelse():

d$A <- with(d, ifelse(A == "D", 9, ifelse(A == "B", 10, A)))

> d
    A B
1   9 7
2   1 8
3   2 9
4   3 4
5   9 5
6   1 8
7   2 9
8  10 1
9   9 6
10  3 7
11  4 8

Comments

0

Since you have a factor variable you can change the levels of this factor via

 func <- function(dat,rep_val_col,rep_val_col_change,new_val)
 {
    levels(dat[,rep_val_col])[levels(dat[,rep_val_col]) == rep_val_col_change[1]] <- new_val[1]
    levels(dat[,rep_val_col])[levels(dat[,rep_val_col]) == rep_val_col_change[2]] <- new_val[2]
    return(dat)
 }

 func(d,"A",c("D","B"),new_val = c(9,10))

2 Comments

This one only add NAs at places of D and B.
Really? It seems to work fine for me though. I get [1] 9 1 2 3 9 1 2 10 9 3 5 with Levels: 1 2 3 5 10 9 for column A.
0

Not sure if you are looking for something in general but you can do a simple replacement using

d$A <- gsub("D", 9, d$A)
d$A <- gsub("B", 10, d$A)

Comments

0

First, note that having a mixture of strings and numerical values in a column will autmatically convert the whole column to a factor (or character in some cases).

In this case, however, having a factor is actually useful as a factor keeps track of unique values as levels that we can change using match and replace.

First, check the levels of d$A:

levels(d$A)
[1] "1" "2" "3" "5" "B" "D"

We can then find the indexes of "B" and "D" using match:

match(c('D','B'), levels(d$A))
[1] 6 5

And replace them using replace:

replace(levels(d$A), match(c('D','B'), levels(d$A)), c(9, 10))
[1] "1"  "2"  "3"  "5"  "10" "9" 

Note that the levels are still of type character. Save the new levels and convert the d$A to numeric:

levels(d$A) <- replace(levels(d$A), match(c('D','B'), levels(d$A)), c(9, 10))
d$A <- as.numeric(as.character(d$A))

1 Comment

Thanks for the explanation. It also explains Adam's answer

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.