Sana Ali
Sana Ali

Reputation: 185

replacing string with numeric character in a column through function in R

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.

Upvotes: 4

Views: 3857

Answers (6)

akrun
akrun

Reputation: 887951

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

Upvotes: 2

ssokolen
ssokolen

Reputation: 478

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

Upvotes: 0

hbabbar
hbabbar

Reputation: 967

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)

Upvotes: 0

theSZ
theSZ

Reputation: 73

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

Upvotes: 0

LAP
LAP

Reputation: 6695

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

Upvotes: 0

Adam Quek
Adam Quek

Reputation: 7163

levels(d$A)[levels(d$A) %in% c("B", "D")] <- c(9, 10)
d$A <- as.numeric(as.character(d$A))

Upvotes: 4

Related Questions