Home > Software engineering >  An if statement returns a different variable on each branch, how can I sub-assign to that variable u
An if statement returns a different variable on each branch, how can I sub-assign to that variable u

Time:09-26

Consider

a <- b <- 1:3
if(sample(2, 1) == 1) a[2] <- 5 else b[2] <- 5

This is repetitive. I would not like to have to write <- 5 twice. It would be ideal to use

a <- b <- 1:3
assign(if(sample(2, 1) == 1) "a[2]" else "b[2]", 5)

but assign is no good for sub-assignment. What idiomatic alternatives exist?

CodePudding user response:

I think the idiomatic way to do it is not to have two variables, let them be entries in a list:

l <- list()
l$a <- l$b <- 1:3
var <- sample(c("a", "b"), 1)
l[[var]][2] <- 5
l
#> $b
#> [1] 1 2 3
#> 
#> $a
#> [1] 1 5 3

Created on 2021-09-26 by the reprex package (v2.0.0)

You could get something closer to what you were asking for by fooling around with environments:

a <- b <- 1:3
var <- sample(c("a", "b"), 1)
e <- environment()
e[[var]][2] <- 5

Created on 2021-09-26 by the reprex package (v2.0.0)

but I wouldn't call this idiomatic.

CodePudding user response:

I don't think there's an idiomatic way to do this, but it is certainly possible to do it with a single assignment:

a <- b <- 1:3
s <- if(sample(2, 1) == 1) "a" else "b"
assign(s, `[<-`(get(s), 2, 5))

a
#> [1] 1 2 3

b
#> [1] 1 5 3

Created on 2021-09-26 by the reprex package (v2.0.0)

CodePudding user response:

You could use an eval(parse()) approach.

eval(parse(text=paste(c('a', 'b')[(sample(2, 1) == 1)   1], '[2] <- 2')))

Or short:

eval(parse(text=paste(sample(c('a', 'b'), 1), '[2] <- 2')))
  • Related