Harrison Garcia
Harrison Garcia

Reputation: 11

I want to replace each value in vector x with "Yes" if corresponding value from vector y isn't "No"

Using this code in R:

x <- c("No", "Yes", "No")
y <- c("Yes", "No", "No")
df <- data.frame(x, y)

my.yes <- function(x,y) {
  for (i in length(x)){
  x[i] <<- ifelse(x[i]=="No" && y[i]!="No", "Yes", "No")
  }
}

my.yes(df$x, df$y)

I want x in df to be as such: "Yes", "Yes", "No"

Thanks in advance!

Upvotes: 1

Views: 39

Answers (3)

denis
denis

Reputation: 5673

An other bae solution:

deni = function(df){
  df$x[df$y != "No"] <- "Yes"
  return(df$x)
}

Using @ruibarradas benchmark:

Unit: microseconds
   expr      min        lq      mean    median       uq      max neval
   deni  115.201  159.2500  248.8230  208.8015  241.002 3819.700   100
    rui  278.701  344.1005  507.1501  443.7010  485.601 6291.501   100
 akrun1  383.700  511.6010  665.6150  611.8505  699.901 4568.001   100
 akrun2 2990.601 3465.2015 3913.3211 3698.8510 4181.801 8792.201   100

Upvotes: 2

Rui Barradas
Rui Barradas

Reputation: 76402

Here is another option, with an extraction from the vector of return values, c("No", "Yes"), based on the condition.

rui <- function(df){
  c("No", "Yes")[with(df, x == "Yes" | y == "Yes") + 1]
}

rui(df)
#[1] "Yes" "Yes" "No" 

A benchmark gives this one as the fastest of the three, the other two are in akrun's answer.

library(microbenchmark)

akrun.pmax <- function(df) with(df, pmax(x, y))

my.yes <- function(dat) {
  with(dat, ifelse(x == 'Yes'| y == "Yes", 'Yes', 'No'))
}

n <- 1e4
for(i in 1:log2(n/nrow(df))) df <- rbind(df, df)

mb <- microbenchmark(
  rui = rui(df),
  akrun1 = akrun.pmax(df),
  akrun2 = my.yes(df)
)
print(mb, order = "median")
#Unit: microseconds
#   expr      min       lq      mean    median        uq       max neval cld
#    rui  214.828  421.731  642.5115  504.2005  515.6025 10245.114   100 a  
# akrun1  607.604 1358.885 1429.7580 1425.9795 1460.0835  5854.601   100  b 
# akrun2 2086.762 3517.939 3649.5576 3685.4385 3740.8590 10945.852   100   c
 

Upvotes: 1

akrun
akrun

Reputation: 887048

We can use pmax

with(df, pmax(x, y))
#[1] "Yes" "Yes" "No"

In the OP's function, we can change the && to & and remove the loop as ifelse is vectorized

with(df, ifelse(x == 'Yes'| y == "Yes", 'Yes', 'No'))
#[1] "Yes" "Yes" "No" 

which can be wrapped into a function

my.yes <- function(dat) {
        with(dat, ifelse(x == 'Yes'| y == "Yes", 'Yes', 'No'))
   }
my.yes(df)

Upvotes: 1

Related Questions