Reputation: 129
category.1 <- c("TM","TM","CPA","TM","CPC")
category.2 <- c("LS","LS","DSP","DSP","AF")
platform <- c("facebook","facebook","yahoo","google","google")
dat <- data.frame(platform,category.1,category.2)
dat
platform category.1 category.2
1 facebook TM LS
2 facebook TM LS
3 yahoo CPA DSP
4 google TM DSP
5 google CPC AF
when category.1 is 'TM' and category.2 'LS', I wanna replace 'LS' to 'LS1'
platform category.1 category.2
1 facebook TM LS1
2 facebook TM LS1
3 yahoo CPA DSP
4 google TM DSP
5 google CPC AF
I tried this way, its return error.
dat$category.1[dat$category.1=='TM'& dat$category.2=='LS',] <- 'LS1'
thanks for your reading.
Upvotes: 2
Views: 109
Reputation: 92282
If you want a really efficient way of doing replacements by condition, check out the data.table
package and its binary search/replacement by reference
library(data.table)
setkey(setDT(dat), category.1, category.2)
dat[J("TM", "LS"), category.2 := "LS1"][]
# platform category.1 category.2
# 1: yahoo CPA DSP
# 2: google CPC AF
# 3: google TM DSP
# 4: facebook TM LS1
# 5: facebook TM LS1
setDT
converts to data.table
object. setkey
keys the data in order to perform a binary join. J()
performs the actual binary join. :=
performs assigment by reference and updates category.1
in place.
Though if your data set isn't big, you could just do
dat[category.1 == "TM" & category.2 == "LS", category.2 := "LS1"][]
Some benchmarks on a slightly bigger data set (I didn't test base because you need to convert to character class in order for this to work)
library(data.table)
library(dplyr)
library(microbenchmark)
dat2 <- data.frame(lapply(dat, rep, 1e5))
dat3 <- copy(dat2)
dat4 <- copy(dat2)
dplyrfunc <- function(x) {
x <- x %>%
mutate(category.2 =
ifelse(category.1 == "TM" & category.2 == "LS",
"LS1", as.character(category.2)))
x
}
data.tablefunc1 <- function(x){
setkey(setDT(x), category.1, category.2)
x[J("TM", "LS"), category.2 := "LS1"][]
}
data.tablefunc2 <- function(x){
setDT(x)[category.1 == "TM" & category.2 == "LS", category.2 := "LS1"][]
}
## Unit: milliseconds
## expr min lq mean median uq max neval
## dplyrfunc(dat2) 277.261833 291.647719 313.76279 302.337902 335.703250 401.38212 100
## data.tablefunc1(dat3) 5.371047 5.905744 8.12169 6.904871 8.266383 59.83116 100
## data.tablefunc2(dat4) 31.980348 32.870719 38.26239 34.745612 39.309186 88.91202 100
Upvotes: 3
Reputation: 5314
You can set stringsAsFactors = FALSE
when creating your data set
dat <- data.frame(platform,category.1,category.2, stringsAsFactors = FALSE)
Then you can use your code, just remove the comma like this
dat$category.2[dat$category.1=='TM'& dat$category.2=='LS'] <- "LS1"
Upvotes: 4
Reputation: 759
Another approach; using dplyr
and the ifelse
base function.
> library(dplyr)
> dat <-
dat %>%
mutate(category.2 = ifelse(category.1 == "TM" & category.2 == "LS",
"LS1",
as.character(category.2)))
> dat
platform category.1 category.2
1 facebook TM LS1
2 facebook TM LS1
3 yahoo CPA DSP
4 google TM DSP
5 google CPC AF
Upvotes: 6
Reputation: 7654
You can use revalue
from the plyr
package:
library(plyr)
dat$category.2 <- revalue(dat$category.2, c("LS" = "LS1"))
dat
platform category.1 category.2
1 facebook TM LS1
2 facebook TM LS1
3 yahoo CPA DSP
4 google TM DSP
5 google CPC AF
Upvotes: 1