Cleb
Cleb

Reputation: 26027

Replace values in one column based on condition using its name as a string

If I have a dataframe like this:

df <- data.frame(c1=1:6, c2=2:7)

I can happily replace values in c2 that are larger then 4 doing

df$c2[df$c2 > 4] <- 10

yielding the desired output

  c1 c2
1  1  2
2  2  3
3  3  4
4  4 10
5  5 10
6  6 10

However, I want to select the column by its name using a string, in this case "c2", as the column selection should not be hard-coded but it is context dependent.

The best I could come up with is

df[,c('c2')][df[,c('c2')] > 4] <- 1000

yielding

  c1   c2
1  1    2
2  2    3
3  3    4
4  4 1000
5  5 1000
6  6 1000

It works, but I find it rather ugly. Is there a better way of doing the same thing?

Upvotes: 1

Views: 453

Answers (4)

akrun
akrun

Reputation: 887531

Using transform and ifelse

transform(df, c2 = ifelse(c2 > 4, 100, c2))
#  c1  c2
#1  1   2
#2  2   3
#3  3   4
#4  4 100
#5  5 100
#6  6 100

If we need to pass a string, one option with dplyr, would be convert to symbol and evaluate

library(dplyr)
df %>%
     mutate(!! "c2" := replace(!! rlang::sym("c2"), 
           !! rlang::sym("c2")  > 4, 100))
#  c1  c2
#1  1   2
#2  2   3
#3  3   4
#4  4 100
#5  5 100
#6  6 100

Upvotes: 2

NelsonGon
NelsonGon

Reputation: 13319

If one is open to packages, we can use purrr's modify_at or dplyr's mutate_at

purrr::modify_at(df,"c2",
                 function(x) 
                   ifelse(x>4,100,x))

With dplyr:

mutate_at(df,"c2",
                 function(x) 
                   ifelse(x>4,100,x))

Upvotes: 2

Ronak Shah
Ronak Shah

Reputation: 389155

Maybe using replace

df['c2'] <- replace(df['c2'], df['c2'] > 4, 100)
df

#  c1  c2
#1  1   2
#2  2   3
#3  3   4
#4  4 100
#5  5 100
#6  6 100

Or something similar as your attempt

df['c2'][df['c2'] > 4] <- 100

Upvotes: 2

s_baldur
s_baldur

Reputation: 33548

df[df$c2 > 4, 'c2'] <- 10
# or
df$c2 <- with(df, replace(c2, c2 > 4, 10)) 

Using package data.table you could do:

library(data.table)
setDT(df)
df[c2 > 4, c2 := 10]

Upvotes: 1

Related Questions