Hi Travis,
Others will probably have better insights.
The only part that would be able to be replaced with a recursive call in logmodr seems to be the loop itself. It is walking the list/vector y from the second element to t (which... does numeric on a vector coerce it to a length? I have no idea what numeric(t) does in this context. I sometimes lose my mind trying to think about everything in R as a vector, and where/when different functions do different things depending on what you pass as a value...).
My termination condition is when i is equal to t, and otherwise, I do the calculation, attaching the current calculation to the result of calculating the rest of the values in the range. (In the for loop in the original logmodr, this comes out looking like assignment to a vector, but we'll cons up a list instead.) I have no idea if my pseudocode below puts the list in the correct order... that could be fixed in a number of ways.
If I were translating this code, I would personally consider allocating the vector and just doing the direct transliteration with a for loop. I don't know that I would try and convert the code to a recursive call... but, as a learning exercise, it makes sense why you're thinking about it.
The HtDP design recipe helps in thinking about how to break these kinds of questions down. In this case, I had to think about whether there was a recursion over a list/vector (there doesn't seem to be), but instead it seemed like I'm building up my results in a list/vector. Therefore, I needed to think about the recursion on the range of numbers and choose my termination condition accordingly. From there, I also needed to figure out what information was initialization, and what information needed to be passed through the loop. Ultimately, I might pass a fair number of parameters, but that's because I have to maintain the correct local scope for each recursive call. I could also use an internal function definition for some of these things, so that values that don't change are defined once, and the function that is implementing the loop closes over those values just once. This would cut... theta from the list of parameters, and possibly also k and r, because they don't change. (Ha! K&R don't change. That's a C pun!)
Bad humor aside, my point was that I could probably define a calc function that had an internal calc* function (using either an internal define or a letrec), and it would only take i and y as parameters. calc* would then implement the "loop".
Someone will, no doubt, post a cleaner example that is three lines long and only uses letrec and lambda, but here was my take on your question. But, this was more fun then getting started on grading.
Cheers,
Matt
(define (rnorm t thetasd)
(list 1 2 1))
(define (calc i y t r k theta)
(cond
[(= i t) '()]
[else
(cons (* (list-ref y (sub1 i))
(- r (* (/ (* r (list-ref y (sub1 i))) k)
(exp (list-ref theta i)))))
(calc (add1 i) y t r k theta))]))
(define (logmodr yinit t r k thetasd)
(let ([y (list yinit)]
[theta (rnorm t 0 thetasd)])
(calc 0 y t r k theta)))