There are a few things with your code:
as @MillionC pointed out, your conditional is syntactically wrong, it should have more enclosing parens as in if ((i+j)==1) {...
the first time lp(...) is called, it is being assigned to ans[0.1], which is nonsensical, you probably need to iterate over the indices of a1 (and optionally a2)
your pre-allocation of ans is not necessarily wrong, but pre-allocating does very little unless you tell it its size; I suggest ans <- vector('numeric', length(a1)) or just ans <- numeric(length(a1))
perhaps you trivialized the example for the question, but just in case ... you do not need two loops, when your conditional allows you to know ahead of time which combinations of i and j are relevant; in this case, you only need j when it is perfectly 1-i, so you can remove a loop entirely.
You could use:
ans <- vector('numeric', length(a1))
for (indi in seq_along(a1)) {
for (indj in seq_along(a2)) {
if ((a1[indi]+a2[indj]) == 1) {
ans[indi] <- 99 + a1[indi]
}
}
}
ans
# [1] 99.1 99.2 99.3 99.4 99.5 99.6 99.7 99.8 99.9 0.0
or slightly better:
ans <- vector('numeric', length(a1))
for (indi in seq_along(a1)) {
ans[indi] <- 99 + a1[indi]
}
ans
# [1] 99.1 99.2 99.3 99.4 99.5 99.6 99.7 99.8 99.9 100.0
(I don't have lpSolve, so I'm masquerading with "99".) The big difference here is the value of the last call: in your double-loop, there is never a value in a2 that when added to the a1 value of 1 equals 1. However, the second run does not check for that, so ... it does something. (Only you know which method is correct.)
Nested loops are not necessarily wrong, but in general I suggest you think about how to vectorize something. Instead of looping over things in ways you'd expect to in C or Java (and sometimes Python), think about doing things to a vector all at once. Sometimes this is as simple as replacing
vec <- 1:10
for (ind in seq_along(vec)) vec[ind] <- vec^2
to
vec <- 1:10
vec <- vec^2
as long as the function supports a vector as an input. When it is not supported or is not as simple as thing, then sapply and lapply are sort of like a for loop but capturing each return value, so you can do something like
ans <- sapply(seq_along(a1), function(indi) 99 + a1[indi])
ans
# [1] 99.1 99.2 99.3 99.4 99.5 99.6 99.7 99.8 99.9 100.0
Care must be taken to not go too literally with this. For instance, converting your conditioned double-lool, we would get:
ans <- sapply(seq_along(a1), function(indi) {
sapply(seq_along(a2), function(indj) {
if ((a1[indi]+a2[indj]) == 1) {
99 + a1[indi]
} else {
# something here?
}
})
})
ans
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
# [1,] NULL NULL NULL NULL NULL NULL NULL NULL 99.9 NULL
# [2,] NULL NULL NULL NULL NULL NULL NULL 99.8 NULL NULL
# [3,] NULL NULL NULL NULL NULL NULL 99.7 NULL NULL NULL
# [4,] NULL NULL NULL NULL NULL 99.6 NULL NULL NULL NULL
# [5,] NULL NULL NULL NULL 99.5 NULL NULL NULL NULL NULL
# [6,] NULL NULL NULL 99.4 NULL NULL NULL NULL NULL NULL
# [7,] NULL NULL 99.3 NULL NULL NULL NULL NULL NULL NULL
# [8,] NULL 99.2 NULL NULL NULL NULL NULL NULL NULL NULL
# [9,] 99.1 NULL NULL NULL NULL NULL NULL NULL NULL NULL
# [10,] NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL
... which is likely not correct for you. It is not hard to correct for this, but in general you probably want to run the loop only where needed, not 10x the runs.
In another extreme solution, you know the values of a2 that are relevant for each in a1, then consider pre-allocating them and using a cousin of sapply:
myfunc <- function(i, j) lp("max", c(i,j), f.con, f.dir, f.rhs)$objval
ans <- mapply(myfunc, a1, a2)
(I pre-defined myfunc for demonstration purposes; it's legit and common to put the function(i,j)... directly as the first argument to mapply, as I did for the second argument to sapply above.)
This is a "zipper" like function, where the calls are effectively
myfunc(i[1], j[1])
myfunc(i[2], j[2])
myfunc(i[3], j[3])
...
myfunc(i[10], j[10])
captured into a vector. This method might be more appropriate for you, where you know the pairs of arguments that need to be given as a vector to the second argument in lp(..., c(i,j), ...).
(Note: mapply can take an arbitrary number of arguments, so it could also do
mapply(function(w,x,y,z) { ... },
list(...), list(...), list(...), list(...))
The only requirement is that each list is either the same length or length 1.)
ans <- lapply(seq(0.1,1,0.1), function(i) lp("max", c(i,1-i), f.con, f.dir, f.rhs)$objval)might work.lp(), you are trying to assing it toans[0.1], which is meaningless. You might have been able to dofor (ind in seq_along(i)) ans[ind] <- lp("max", c(i[ind], 1-i[ind]), ...)$objval)as well. In R, though, I suggest you should learn to think about things in vectorizing mechanisms (often using one of theapplyfunctions), where its efficiency really shines.