Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace value in column with corresponding value from another column in same dataframe

Im trying to match a specific value in one column and replace it with the corresponding value from another column (same row). This is probably very easy... I have been trying to find a solution with for loop, sub, subset, data.table but I have not succeeded. There must be a neat way of doing this.

Example data, where we aim at swapping a in the first column with the corresponding value in the second column and outputting the column again.

df <- data.frame(rbind(c('a','D'),c('H','W'),c('Q','E'),c('a','F'),c('U','P'),c('a','B')))

df$X1 <- as.character(df$X1)
df$X2 <- as.character(df$X2)

# not working
for (i in seq_along(df$X1)){
  a <- df$X1[i]
  b <- df$X2[i]
  x <- ifelse(a[i=='a'], a[i]<-b[i], do.nothing )
  print(x)
}

The output would be like this;

   X1 X2
1  D  a
2  H  W
3  Q  E
4  F  a
5  U  P
6  B  a

(The switch isn't necessary). It's the first column Im interested in.

Any pointer would be appreciated, thanks!

like image 406
jO. Avatar asked Nov 24 '25 19:11

jO.


2 Answers

There are several alternatives. Here are three:

Most basic, using data.frames :

df[ df$X1 == "a" , "X1" ] <- df[ df$X1 == "a", "X2" ]

More Terse, using with:

df$X1 <- with( df, ifelse( X1 == "a", X2, X1 ) )

Most terse and transparent Using data.tables

library(data.table) ## >= 1.9.0
setDT(df)           ## converts to data.table by reference, no need for `<-`

df[ X1 == "a", X1 := X2 ]
like image 168
ctbrown Avatar answered Nov 26 '25 07:11

ctbrown


Here's another approach if you have more than one condition (swap "a" for a vector of values).

> find.a <- df$X1 %in% "a"
> df[find.a, "X1"] <- df[find.a, "X2"]
> df
  X1 X2
1  D  D
2  3  W
3  Q  E
4  F  F
5  U  P
6  B  B
like image 33
Roman Luštrik Avatar answered Nov 26 '25 09:11

Roman Luštrik



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!