0

EDIT: For anyone interested, I completed my little project here and it can be seen at this link http://fdrennan.net/pages/myCurve.html Scroll down to "I think it's been generalized decently" to see the curve_fitter function. If you find it useful, steal it and I don't need credit. I still have ncol as an input but it isn't required anymore. I just didn't delete it.

I am writing a script that will do some least squares stuff for me. I'll be using it to fit curves but want to generalize it. I want to be able to write in "x, x^2" in a function and have it pasted into a matrix function and read. Here is what I am talking about.

expressionInput <- function(func = "A written function", x = "someData", 
                   nCol = "ncol") {

# Should I coerce the sting to something in order to make...
func <- as.SOMETHING?(func)

# ...this line to be equivalent to ...
A <- matrix(c(rep(1, length(x)), func), ncol = nCol)

# .... this line
# A <- matrix(c(rep(1, length(x)), x, x^2), ncol = 3)

A
}

expressionInput(func = "x, x^2", x = 1:10, nCol = 3)

Returns 10 x 3 matrix with 1's in one column, x in second, and squared values in third column.

The link below will show a few different functions for curve fitting. The idea behind this post is to be able to write in "x + x^2" or "x + sin(x)" or "e^x" etc., and return the coefficients for curve. http://fdrennan.net/pages/myCurve.html

  • You might like `purrr::invoke`. Handling functions as strings is a finicky process best avoided, generally speaking. – alistaire Jul 03 '16 at 20:10
  • 1
    In what concept is the generalization you need? If you need to apply different functions to "x" argument you could pass a function as argument instead of `parse`ing a "character". E.g. `expressionInput(func = function(x) x ^ 2, x = 1:10m ncol = 3)` and use it appropriately in your function. With your setup, you need [this](http://stackoverflow.com/questions/1743698/evaluate-expression-given-as-a-string) but see [here](http://stackoverflow.com/questions/13649979/what-specifically-are-the-dangers-of-evalparse) – alexis_laz Jul 03 '16 at 20:11
  • 2
    may I suggest that you use a formula (e.g. `~1+x+I(x^2)`) and the `model.matrix()` function as an easier way of doing this? – Ben Bolker Jul 03 '16 at 20:34
  • 1
    The way this question is phrased is slightly vague. Please let me know if my answer below has correctly interpreted what you are after, and I will try editing to make the question more clear. – dww Jul 03 '16 at 21:01

1 Answers1

0

I think you are looking for something like this

f <- function(expr="", x=NULL, nCol=3) {
  expr <- unlist(strsplit(expr,","))
  ex <- rep("rep(1,length(x))", nCol)
  ex[1:length(expr)] <- expr
  sapply(1:length(ex), function(i) eval(parse(text=ex[i])))
}

f("x, x^2", 1:10, 3)
      [,1] [,2] [,3]
 [1,]    1    1    1
 [2,]    2    4    1
 [3,]    3    9    1
 [4,]    4   16    1
 [5,]    5   25    1
 [6,]    6   36    1
 [7,]    7   49    1
 [8,]    8   64    1
 [9,]    9   81    1
[10,]   10  100    1

Note that, in your example, you separate the expressions to evaluate using a comma (,). Accordingly, I have used a comma to split the string into expressions. If you try passing expressions, which themselves contain commas this will fail. So, either restrict to using simple expressions without commas. Or if this is not possible then use a different character to separate the expressions (and escape it, if you need that character to be evaluated).

However, I would also reiterate the warnings in the comments to your question that depending on what you are trying to achieve, there are likely better ways to do it.

dww
  • 30,425
  • 5
  • 68
  • 111
  • You can scroll down to where it says, "I think it's been generalized decently." I really appreciate your help and I found the solution I was looking for thanks to you. I've self taught myself R and a lot of my solutions have come from brute force. I should work on that. Anyways, it works now. http://fdrennan.net/pages/myCurve.html – Freddy Ray Drennan Jul 03 '16 at 22:24
  • 1
    I apologize, this is my first post here. I just accepted it. Thanks for the reminder. I also checked the uptick but it said users with less than 15 reputation are recorded but not publicly displayed. – Freddy Ray Drennan Jul 03 '16 at 22:56