53

I have the following data.table:

dt <- data.table(col1 = rep("a",6), col2 = c(1,1,1,2,3,1))

Now I want to replace all the 1 in col2 with value "bigDog". I can do it using the data.frame spirit:

dt$col2[dt$col2==1,] <- "bigDog"

But I wonder if there is a different way, more "data.table oriented"?

Jaap
  • 81,064
  • 34
  • 182
  • 193
Colonel Beauvel
  • 30,423
  • 11
  • 47
  • 87

2 Answers2

69

Had you not wanted to change the type of the column, you'd do:

dt[col2 == 1, col2 := 123]

With the type change, you can do:

dt[, col2 := as.character(col2)][col2 == "1", col2 := "bigDog"]

If you don't change the type first, "bigDog" will get coerced to integer, i.e. NA. You'll also get a bunch of warnings about that of course.

Note that besides less cumbersome syntax, using := has the advantage of not making extra copies of data (as <- will) and instead modifies in place.

eddi
  • 49,088
  • 6
  • 104
  • 155
  • Assuming I don't want to change the column type, how can I apply the first usage to multiple (named) columns? – rimorob Jul 01 '15 at 00:26
  • 2
    @rimorob sure - `dt[condition,\`:=\`(col2 = 123, col3 = 234, ...)]` – eddi Jul 01 '15 at 04:21
  • 3
    How about doing multiple conditions at once on the same column? E.g. changing 1 to "bigDog" and 2 to "smallDog"? – bob Feb 05 '20 at 20:10
1

Aditionally you could use the library plyr

library(data.table)
library(plyr)
dt <- data.table(col1 = rep("a",6), col2 = c(1,1,1,2,3,1))
dt <- mapvalues(dt[,col2], c(1), c("BigDog"))
jalazbe
  • 1,801
  • 3
  • 19
  • 40