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')))